2013-06-04 31 views
5

如何使用匿名字段(或超類)獲得正確的結構類型?在Go中,如何使用匿名字段方法獲取TypeOf類型?

我試圖讓這種魚形容自己是鱈魚:

package main 

import (
    "fmt" 
    "reflect" 
) 

type Fish struct { 
} 

func (self *Fish) WhatAmI() string { 
    return reflect.TypeOf(self).String() 
} 

type Cod struct { 
    Fish 
} 

func main() { 
    c := new(Cod) 
    fmt.Println("I am a", c.WhatAmI()) 
} 

我得到的輸出是:

I am a *main.Fish 

我要的是:

I am a *main.Cod 

回答

9

得到正確的答案。 想要得到的答案是錯誤的。

func (f *Fish) WhatAmI() string { 
     return reflect.TypeOf(f).String() 
} 

f*main.Fish,它甚至宣佈是那種類型(f *Fish)的。因此不可能是永遠是*main.Cod類型。

可能的混淆源:Cod的方法集繼承了其嵌入匿名字段Fish的方法集,並且不會覆蓋它。因此,在Cod的實例上調用WhatAmI「委託」Fish.WhatAmI,,但是的調用,接收器現在是*main.Fish類型的嵌入字段。

實施例與重寫繼承的方法:

package main 

import (
     "fmt" 
) 

type Fish struct { 
} 

func (f *Fish) WhatAmI() string { 
     return fmt.Sprintf("%T", f) 
} 

type Cod struct { 
     Fish 
} 

func (c *Cod) WhatAmI() string { 
     return fmt.Sprintf("%T", c) 
} 

func main() { 
     c := new(Cod) 
     fmt.Println("I am a", c.WhatAmI()) 
} 

Playground


輸出:

I am a *main.Cod 
2

對於相當通用的解決方案,可以將WhatAmI函數從Fish分離鍵入並使用空的界面(見Andrew Gerrand's "The Laws of Reflection"),只是檢查該類型:

package main 

import (
    "fmt" 
    "reflect" 
) 

type Fish struct { 
} 

type Cod struct { 
    Fish 
} 

func WhatAmI (self interface{}) string { 
    return reflect.TypeOf(self).String() 
} 

func main() { 
    c := new(Cod) 
    fmt.Println("I am a", WhatAmI(c)) 
} 

給出:

I am a *main.Cod 
+0

如果目標是要知道從'Fish'方法的類型,不會幫助:這些方法的接收器即使嵌入到另一個結構中也將是一個'Fish'。 –

相關問題