我是个新手,在访问运行时未知结构的数据时遇到了问题:
type Nested struct {
Value string
}
type TypeA struct {
Nested
Foo string
}
type TypeB struct {
Nested
Bar string
}
我必须实现以下回调:
func Callback(param interface{}) {
}
param
可以是*TypeA
或*TypeB
。
如何强制转换类型转换/强制转换param
,以便访问两种类型通用的已知Nested
元素?
因为接口是隐式实现的,所以我认为我可以这样做
type Whatever struct {
Nested
}
然后
func Callback(param interface{}) {
nst := param.(*Whatever)
fmt.Printf(nst.Nested.Value)
}
然而,这会导致
interface {} is *misc.TypeA, not *misc.Whatever
提前感谢您的帮助。
发布于 2020-10-12 15:30:21
如果param
中的动态值是*misc.TypeA
类型,则只能type assert *misc.TypeA
。
这样做,您就可以访问Nested
字段:
func Callback(param interface{}) {
nst := param.(*TypeA)
fmt.Printf(nst.Nested.Value)
}
如果它可以是更多类型的值,请使用type switch
func Callback(param interface{}) {
switch nst := param.(type) {
case *TypeA:
fmt.Println(nst.Nested.Value)
case *TypeB:
fmt.Println(nst.Nested.Value)
}
}
测试:
a := &TypeA{
Nested: Nested{Value: "val"},
}
Callback(a)
b := &TypeB{
Nested: Nested{Value: "val"},
}
Callback(b)
输出(在Go Playground上试用):
val
val
如果您打算在所有情况下都执行相同的操作,则可以像这样减少代码:
func Callback(param interface{}) {
var nst Nested
switch x := param.(type) {
case *TypeA:
nst = x.Nested
case *TypeB:
nst = x.Nested
}
fmt.Println(nst.Value)
}
这将输出相同的内容。在Go Playground上试试。
当然,最好的方法是使用接口。使用带有GetNested() Nested
方法的接口,并让您的类型实现它。并更改Callback()
以接受此接口类型的值。由于您已经在使用嵌入(将Nested
嵌入到TypeA
和TypeB
中),因此只需在Nested
本身上实现一次此GetNested()
函数就很方便:
func (n Nested) GetNested() Nested {
return n
}
type HasNested interface {
GetNested() Nested
}
func Callback(nst HasNested) {
fmt.Println(nst.GetNested().Value)
}
仅此而已。这将再次输出相同的内容。在Go Playground上试试这个。
https://stackoverflow.com/questions/64313331
复制相似问题