2016-08-25 92 views
3

我有一些不同的结构像BigSmall嵌入在偏移0 如何访问Small的结构域从代码,不知道Big类型什么,但是已知Small在偏移量0?Golang:转换结构嵌入在偏移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类型已Small型嵌入式偏移量为0。有没有办法做这样的事情(可能与unsafe.Pointer)?

+0

忽略 - 没有真正的问题妥善 – Sridhar

回答

1

虽然回答反思工作,但它有性能处罚,并没有惯用的去。

我相信你应该使用接口。像这样

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 
+1

对我来说没问题,谢谢 – Exel

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) 

输出(尝试在Go Playground):

main.Small{val:1} 
1 

注:以上任务可以使用反射(reflect包)来完成

这适用于任何领域,不只是第一个(在“偏移0”处)。这也适用于命名字段,不仅适用于嵌入字段。但这对于未报告的字段不起作用。

+0

为什么不直接投射到大,然后采取v.val或v.Small.val ? 反射在这里是过度的,不是吗? –

+0

@AlexanderTrakhimenok Asker想要一种我们不知道“大”的方式。转换或提取“Big”类型的值不符合该条件。 – icza

1
type Small struct { 
    val int 
} 

type Big struct { 
    Small 
    bigval int 
} 

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

但是asker的'v'变量的类型是'interface {}',你的类型是'Big'。 – icza

+0

Ops!我看错了!在这种情况下,你的答案是正确的! – gianlucatursi