Golang:将结构转换为嵌入在偏移量 0 处的结构
Golang: convert struct to embedded at offset 0 struct
我有一些不同的结构,例如 Big
和 Small
嵌入在偏移量 0 处。
我如何从代码访问 Small
的结构字段,它对 Big
类型一无所知,但已知 Small
位于偏移量 0?
type Small struct {
val int
}
type Big struct {
Small
bigval int
}
var v interface{} = Big{}
// here i only know about 'Small' struct and i know that it is at the begining of variable
v.(Small).val // compile error
似乎编译器在理论上能够操作这样的表达式,因为它知道 Big
类型在偏移量 0 处嵌入了 Small
类型。有没有办法做这样的事情(也许用unsafe.Pointer
)?
避免使用 unsafe
whenever possible. The above task can be done using reflection (reflect
包):
var v interface{} = Big{Small{1}, 2}
rf := reflect.ValueOf(v)
s := rf.FieldByName("Small").Interface()
fmt.Printf("%#v\n", s)
fmt.Printf("%#v\n", s.(Small).val)
输出(在 Go Playground 上尝试):
main.Small{val:1}
1
备注:
这适用于任何领域,而不仅仅是第一个领域("offset 0")。这也适用于命名字段,而不仅仅是嵌入字段。不过,这不适用于未导出的字段。
type Small struct {
val int
}
type Big struct {
Small
bigval int
}
func main() {
var v = Big{Small{10},200}
print(v.val)
}
虽然反射式答案有效,但它有性能损失并且不是 Go 的惯用语言。
我相信你应该使用接口。像这样
https://play.golang.org/p/OG1MPHjDlQ
package main
import (
"fmt"
)
type MySmall interface {
SmallVal() int
}
type Small struct {
val int
}
func (v Small) SmallVal() int {
return v.val
}
type Big struct {
Small
bigval int
}
func main() {
var v interface{} = Big{Small{val: 3}, 4}
fmt.Printf("Small val: %v", v.(MySmall).SmallVal())
}
输出:
Small val: 3
我有一些不同的结构,例如 Big
和 Small
嵌入在偏移量 0 处。
我如何从代码访问 Small
的结构字段,它对 Big
类型一无所知,但已知 Small
位于偏移量 0?
type Small struct {
val int
}
type Big struct {
Small
bigval int
}
var v interface{} = Big{}
// here i only know about 'Small' struct and i know that it is at the begining of variable
v.(Small).val // compile error
似乎编译器在理论上能够操作这样的表达式,因为它知道 Big
类型在偏移量 0 处嵌入了 Small
类型。有没有办法做这样的事情(也许用unsafe.Pointer
)?
避免使用 unsafe
whenever possible. The above task can be done using reflection (reflect
包):
var v interface{} = Big{Small{1}, 2}
rf := reflect.ValueOf(v)
s := rf.FieldByName("Small").Interface()
fmt.Printf("%#v\n", s)
fmt.Printf("%#v\n", s.(Small).val)
输出(在 Go Playground 上尝试):
main.Small{val:1}
1
备注:
这适用于任何领域,而不仅仅是第一个领域("offset 0")。这也适用于命名字段,而不仅仅是嵌入字段。不过,这不适用于未导出的字段。
type Small struct {
val int
}
type Big struct {
Small
bigval int
}
func main() {
var v = Big{Small{10},200}
print(v.val)
}
虽然反射式答案有效,但它有性能损失并且不是 Go 的惯用语言。
我相信你应该使用接口。像这样
https://play.golang.org/p/OG1MPHjDlQ
package main
import (
"fmt"
)
type MySmall interface {
SmallVal() int
}
type Small struct {
val int
}
func (v Small) SmallVal() int {
return v.val
}
type Big struct {
Small
bigval int
}
func main() {
var v interface{} = Big{Small{val: 3}, 4}
fmt.Printf("Small val: %v", v.(MySmall).SmallVal())
}
输出:
Small val: 3