go - go中的类型转换
问题描述
我是新手,在访问运行时未知的结构数据时遇到问题:
type Nested struct {
Value string
}
type TypeA struct {
Nested
Foo string
}
type TypeB struct {
Nested
Bar string
}
我必须实现以下回调:
func Callback(param interface{}) {
}
param
可以是*TypeA
或*TypeB
。
如何转换 type-convert/cast 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
提前感谢您的帮助。
解决方案
如果 in 中的动态值param
是 type *misc.TypeA
,则只能键入 assert *misc.TypeA
。
这样做,然后您可以访问该Nested
字段:
func Callback(param interface{}) {
nst := param.(*TypeA)
fmt.Printf(nst.Nested.Value)
}
如果它可以是更多类型的值,请使用类型开关:
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
intoTypeA
和TypeB
),因此可以方便地GetNested()
在其自身上实现一次此功能Nested
:
func (n Nested) GetNested() Nested {
return n
}
type HasNested interface {
GetNested() Nested
}
func Callback(nst HasNested) {
fmt.Println(nst.GetNested().Value)
}
就这样。这将再次输出相同的内容。在Go Playground上试试这个。
推荐阅读
- javascript - DropZone JS 和 Laravel 块文件上传失败
- steam - 如何使用 Steam Web API 仅获取 Steam 游戏的完整列表(无 DLC、无预告片等)
- javascript - 警报有时工作有时在JS中不起作用
- docker - Asp.Net 核心的 Docker 文件位置
- javascript - 有没有办法在收到 BroadcastChannel 消息后只回复发件人?
- laravel - 如何在 Laravel Controller 上设置全局变量?
- python - 在比较没有键列的 PySpark 数据帧时,是否有任何替代完全外连接的方法?
- c - 存储在 %edx 中的内容以及如何通过 c 代码获取其中的 var?
- xamarin - 可以将 Xamarin Forms 应用程序转换为 Nuget 包吗?
- python - ValueError:无法插入集群标签,已存在