【问题标题】:Type assertions with interface embedding in Go在 Go 中嵌入接口的类型断言
【发布时间】:2021-02-10 02:03:36
【问题描述】:
  • 我有一个接口,它嵌入到多个结构中 形成一个装饰器模式。
  • 现在我添加了代码以将ValidatorAPIService 类型转换到API 接口。因此,如果我在界面中添加一个函数,那么我应该能够将其添加到 ValidatorAPIService

但这段代码似乎可以编译。 我应该得到一个编译器错误,因为我没有在 Validator 上实现 Get 如果我从 APIService 中删除 Get,我会收到一条错误消息,提示我无法将 *APIService 类型转换为 API,因为 get 未实现。

package main

import "fmt"

type API interface {
  Get()
}
var _ API = (*Validator)(nil)
var _ API = (*APIService)(nil)

type APIService struct {
  id string
}

type Validator struct {
  API
}

type APIRouter struct {
  API
}

func(a *APIService) Get(){
  fmt.Println("Calling Get api on APIService")
}

func NewAPIRouter() *APIRouter{
  return &APIRouter{
    API: &Validator{
      API: &APIService{
      },
    },
  }
}
func main() {
  var api API = NewAPIRouter()
  api.Get()
}

如果我编译上面的代码:

./main
Calling Get api on APIService

但如果我在APIService 上评论Get 函数,我会得到以下有效的错误:

go build
# main
./main.go:9:5: cannot use (*APIService)(nil) (type *APIService) as type API in assignment:
    *APIService does not implement API (missing Get method)

我之前应该遇到编译器错误,并且我还没有在 Validator 上实现 Get 如果我从APIService 中删除Get,我会收到一条错误消息,提示我无法将*APIService 类型转换为API,因为get 没有实现。

【问题讨论】:

  • 您选择通过嵌入接口来定义方法,这意味着它将满足类型断言。在 nil 接口上调用方法是运行时错误,而不是编译时错误。
  • 导入行后面的代码。 var _ API = (*Validator)(nil)这条线应该失败了吧?
  • @DineshGowda 不,Validator 类型满足使用从字段API 提升的Get 方法的接口。

标签: go interface casting type-assertion


【解决方案1】:

APIService 类型是一个带有Get 方法的结构体,所以它实现了API 接口。

Validator 类型是一个带有嵌入式接口API 的结构。这意味着,Validator 实例有一个实现API 接口的嵌入成员,并且由于它是嵌入的,Validator 也实现了API 接口。但是,请注意,您必须先将 Validator.API 初始化为实现。像这样的东西应该可以工作:

v:=Validator{API:&APIService{}}

这样,v.Get() 将调用嵌入的APIService.Get

【讨论】:

  • 导入行后的代码。 var _ API = (*Validator)(nil) 这行应该失败了吧?
  • 没有。 *Validator 由于提升了方法而影响了API 接口。
猜你喜欢
  • 1970-01-01
  • 2016-05-26
  • 2021-05-24
  • 2018-11-19
  • 2016-12-13
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多