Golang:将struct转换为嵌入在offset 0 struct

时间:2016-08-25 10:40:20

标签: go struct interface embedding

我有一些不同的结构,例如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类型。是否有任何方法可以执行此类操作(可能使用{{ 1}})?

3 个答案:

答案 0 :(得分:1)

尽可能避免使用jsfiddle.net/b54c38hj/1/。上述任务可以使用反射(unsafe包)完成:

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)

输出(在reflect上尝试):

main.Small{val:1}
1

备注:

这适用于任何领域,而不仅仅是第一个领域(在"偏移0和#34;)。这也适用于命名字段,不仅适用于嵌入字段。但这对于未导出的字段不起作用。

答案 1 :(得分:1)

type Small struct {
    val int
}

type Big struct {
    Small
    bigval int
}

func main() {
    var v = Big{Small{10},200}
    print(v.val)
}

答案 2 :(得分:1)

虽然用反思回答是有效的,但它有性能损失,并不是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