2 回答

TA贡献1804条经验 获得超3个赞
您永远无法将一种具体类型转换为另一种具体类型。它们不一样。在 Go 中无法定义这种类型的自动转换。充其量,您可以定义一个函数,该函数接受 aBar
并构建并返回一个新Foo
的,其字段设置为与输入相同的值Bar
。
我读过的所有内容都告诉我,如果底层类型相同,则高阶类型被认为是兼容的,类型转换会隐式发生
目前还不清楚你的来源是什么,但没有任何东西会说明或暗示这一点,这根本不是真的。Go 不进行任何隐式转换。这是 Go 的一个大声宣传的功能。鉴于type Foo struct { a int }
and type Bar struct { a int }
,您永远不能将类型的对象分配给类型Bar
的变量Foo
。
当类型满足接口时,您可以从任一具体类型转换为接口类型。您的AcceptBarOrFoo
方法应该接受接口类型(两者都Foo
满足Bar
),而不是具体类型。鉴于接口只定义方法(不是成员),并且既没有方法Foo
也Bar
没有任何方法,您的接口将是空接口,interface{}
. 传入的值没有任何用处,除非您稍后将其转换回具体类型以访问其成员,但这并不是接口的真正用途。

TA贡献1864条经验 获得超2个赞
Foox与 Bar 不同,x因为非导出标识符在包边界之间永远不相等。通过导出foo.Foo 和 bar.Bar 中的字段来修复:
type Foo struct {
iface.FooI
X string // <-- start with capital letter to export
}
要使用 foo.Foo 或 bar.Bar 作为参数值,foo.Foo 和 bar.Bar 必须可分配给参数的类型。使用 foo.Foo 作为参数类型是行不通的,因为命名类型不能相互分配。但是,当两种类型共享相同的基础类型时,命名类型可分配给未命名类型。将参数声明为未命名类型:
func AcceptBarOrFoo(struct {
iface.FooI
X string
}) interface{} {
return nil
}
通过这些更改,可以编译以下代码:
AcceptBarOrFoo(bar.Bar{})
AcceptBarOrFoo(foo.Foo{})
在 Go 操场上运行示例
另一种选择是使用到通用类型的转换。在下面的代码中,foo.Foo 是普通类型,bar.Bar 被转换为 foo.Foo。
func Accept(foo.Foo) interface{} {
return nil
}
...
Accept(foo.Foo{})
Accept(foo.Foo(bar.Bar{}))
在 Go playground 上运行示例。
注意:foo.Foo 和 bar.Bar 必须具有相同的字段才能使上述工作正常(导出字段名称,字段顺序相同,字段类型相同)。
关于 Go 的一些注意事项:
存在从一种具体类型到另一种具体类型的转换。
Go 以表达式中没有隐式转换而闻名,但在某些赋值场景中存在隐式转换。
- 2 回答
- 0 关注
- 161 浏览
添加回答
举报