Golang 结构类型转换

我试图弄清楚 go 如何处理结构之间的类型转换。我读过的所有内容都告诉我,具有相同底层类型的类型被认为是兼容的,并且类型转换是隐式发生的。如果是这样,为什么下面的代码不起作用?Foo和都Bar实现了FooI接口,并且都添加了一个x字符串类型的属性。然而,当我将一个类型结构传递给需要类型Bar结构AcceptBarOrFoo的结构时Foo,我得到了一个类型不匹配的编译错误。


去游乐场

package main


import (

    "play.ground/bar"

    "play.ground/foo"

)


func main() {

    AcceptBarOrFoo(bar.Bar{})

}


func AcceptBarOrFoo(foo.Foo) interface{} {

    return nil

}


// -- iface/iface.go --


package iface


type FooI interface {

    a() string

    b(int) int

}

// -- foo/foo.go --

package foo


import (

    "play.ground/iface"

)


type Foo struct {

    iface.FooI

    x string

}

// -- bar/bar.go --

package bar


import (

    "play.ground/iface"

)


type Bar struct {

    iface.FooI

    x string

}


摇曳的蔷薇
浏览 162回答 2
2回答

狐的传说

您永远无法将一种具体类型转换为另一种具体类型。它们不一样。在 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{}. 传入的值没有任何用处,除非您稍后将其转换回具体类型以访问其成员,但这并不是接口的真正用途。

慕斯王

Foox与 Bar 不同,x因为非导出标识符在包边界之间永远不相等。通过导出foo.Foo 和 bar.Bar 中的字段来修复:type Foo struct {&nbsp; &nbsp; iface.FooI&nbsp; &nbsp; X string // <-- start with capital letter to export}要使用 foo.Foo 或 bar.Bar 作为参数值,foo.Foo 和 bar.Bar 必须可分配给参数的类型。使用 foo.Foo 作为参数类型是行不通的,因为命名类型不能相互分配。但是,当两种类型共享相同的基础类型时,命名类型可分配给未命名类型。将参数声明为未命名类型:func AcceptBarOrFoo(struct {&nbsp; &nbsp; iface.FooI&nbsp; &nbsp; X string}) interface{} {&nbsp; &nbsp; return nil}通过这些更改,可以编译以下代码:AcceptBarOrFoo(bar.Bar{})AcceptBarOrFoo(foo.Foo{})在 Go 操场上运行示例另一种选择是使用到通用类型的转换。在下面的代码中,foo.Foo 是普通类型,bar.Bar 被转换为 foo.Foo。func Accept(foo.Foo) interface{} {&nbsp; &nbsp; return nil}...&nbsp;Accept(foo.Foo{})Accept(foo.Foo(bar.Bar{}))在 Go playground 上运行示例。注意:foo.Foo 和 bar.Bar 必须具有相同的字段才能使上述工作正常(导出字段名称,字段顺序相同,字段类型相同)。关于 Go 的一些注意事项:存在从一种具体类型到另一种具体类型的转换。Go 以表达式中没有隐式转换而闻名,但在某些赋值场景中存在隐式转换。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go