提问人:richbai90 提问时间:6/22/2022 最后编辑:richbai90 更新时间:7/3/2022 访问量:1089
Golang 结构体类型转换
Golang struct type conversion
问:
我试图弄清楚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
}
答:
您永远不能将一种混凝土类型转换为另一种混凝土类型。它们不一样。在 Go 中无法定义这种类型的自动转换。充其量,您可以定义一个函数,该函数接受 并构建并返回一个新的,其字段设置为与输入相同的值。Bar
Foo
Bar
我所读到的所有内容都告诉我,如果基础类型相同,则认为高阶类型是兼容的,并且类型转换是隐式发生的
目前还不清楚你的消息来源是什么,但没有任何内容会说明或暗示这一点,这根本不是真的。Go 不对任何内容进行隐式转换。这是 Go 的一个大而响亮的宣传功能。给定 和 ,您永远不能将 类型的对象赋给 类型的变量。type Foo struct { a int }
type Bar struct { a int }
Bar
Foo
当类型满足接口要求时,可以从任一具体类型转换为接口类型。您的方法应该接受接口类型(两者兼而有之),而不是具体类型。假设接口只定义方法(而不是成员),并且给定两者兼而有或没有任何方法,则接口将是空接口。传入的值没有任何作用,除了稍后将其转换回具体类型以访问其成员之外,但这并不是接口的真正用途。AcceptBarOrFoo
Foo
Bar
Foo
Bar
interface{}
评论
Foo's 与 Bar's 不同,因为非导出标识符在包边界之间永远不会相等。通过导出 foo 中的字段进行修复。Foo 和酒吧。酒吧:x
x
type Foo struct {
iface.FooI
X string // <-- start with capital letter to export
}
要使用 foo.Foo 或酒吧。Bar 作为参数值,一个 foo。Foo 和酒吧。Bar 必须可分配给参数的类型。使用 foo 是行不通的。Foo 作为参数类型,因为命名类型不能相互赋值。但是,当命名类型共享相同的基础类型时,命名类型可分配给未命名类型。将参数声明为未命名类型:
func AcceptBarOrFoo(struct {
iface.FooI
X string
}) interface{} {
return nil
}
通过这些更改,将编译以下代码:
AcceptBarOrFoo(bar.Bar{})
AcceptBarOrFoo(foo.Foo{})
另一种选择是使用转换为通用类型。在以下代码中,foo.Foo 是常见的类型和条形图。Bar 转换为 foo。傅。
func Accept(foo.Foo) interface{} {
return nil
}
...
Accept(foo.Foo{})
Accept(foo.Foo(bar.Bar{}))
注意:foo。Foo 和酒吧。栏必须具有相同的字段才能使上述工作起作用(导出字段名称,字段顺序相同,字段具有相同的类型)。
关于 Go 的一些注意事项:
下一个:Java 中的多重转换
评论
foo.Foo