2016-08-25 91 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