2 回答
TA贡献1874条经验 获得超12个赞
解释可能令人惊讶,但实际上很简单。
foo_gen
被定义为func () (Foo, error)
,所以第一个返回值的类型Foo
是 ,它是一个接口。
任何接口类型的值都是struct
具有两个指针的:指向该接口值中实际保存的具体值和指向(一些内部对象表示)它的类型。关于如何实现接口值的经典且非常好的(如果可能有点生疏)解释是this。
您尝试匹配我们刚刚讨论的签名的实际函数返回一个类型的值Bar
作为它的第一个返回值。该类型是一种struct
类型,它与原始签名所期望的接口值无关。
换句话说,为了让你的函数返回一个类型的值Bar
满足期望接口类型值的签名,Foo
编译器必须生成代码,将返回的值复制Bar
到堆并从中合成一个值Foo
。虽然可能是可行的,但这太含蓄了,否则可能会令人惊讶。
由于几乎相同的原因,编译器不允许将切片分配给[]T
类型变量。[]interface{}
TA贡献1776条经验 获得超12个赞
在类型级别上,这就是正在发生的事情。
问题是 go 编译器无法将 a 提升func () (bar, error))到 afunc () (Foo, error)因为通常 go 值不是covariant。
这样做的结果是有几种方法可以解决这个问题。
一种是改变函数的返回类型:
foo_gen := func () (Foo, error) {
return bar{}, nil
}
这是有效的,因为它能够轻松地将bar{}值提升到一个Foo值。
如果我无法更改生成器函数(这也适用于通道等),另一种方法是将生成器包装在另一个函数中:
bar_gen := func () (bar, error){
return bar{}, nil
}
foo_gen := func() (Foo, error){
foobar, err := bar_gen()
return foobar, err
}
- 2 回答
- 0 关注
- 87 浏览
添加回答
举报