2015-04-18 68 views
1

代碼here在golang,我怎麼能替代嵌入結構的方法

package main 

import "fmt" 

func main() { 
    t16() 
} 

type Base struct { 
    val int 
} 
func (b *Base)Set(i int) { 
    b.val = i 
} 
type Sub struct { 
    Base 
    changed bool 
} 

func (b *Sub)Set(i int) { 
    b.val = i 
    b.changed = true 
} 
func t16() { 
    s := &Sub{} 
    s.Base.Set(1) 
    var b *Base = &s.Base 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 

我要讓子充當基地,但是當我打電話集,子它將標誌着changed.I知道有在golang中沒有多態或代理,但有沒有辦法做到這一點,而不是影響基地?

修訂

我希望當我打電話Base.Set它將標誌着在變化,用戶,他們不知道他們實際使用的分,這樣我就可以監視基地的行爲。

func t16() { 
    s := &Sub{} 
    var b *Base = &s.Base 
    b.Set(10) 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 

回答

0

我想我應該使用接口在這裏,它達到我想要的,反而影響了基礎

func main() { 
    t16() 
} 

type Base interface { 
    Set(int) 
} 
type base struct { 
    val int 
} 
func (b *base)Set(i int) { 
    b.val = i 
} 
type Sub struct { 
    base 
    changed bool 
} 

func (b *Sub)Set(i int) { 
    b.val = i 
    b.changed = true 
} 
func t16() { 
    s := &Sub{} 
    s.Set(1) 
    var b Base = s 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 
4

通過具有Sub嵌入Base它會自動具有全部由Base的領域和功能作爲Sub的頂級成員提供。這意味着您可以直接調用s.val,你能夠調用s.Set調用基函數除了的事實,Sub都實現了自己Set方法,隱藏基地之一。

當您在示例中調用s.Base.Set()時,您將繞過Sub.Set()並直接呼叫Base.Set()

要解決它在你的情況就像調用s.Set()而不是s.Base.Set()一樣簡單。

這個工作對我來說:

func (b *Sub)Set(i int) { 
    b.Base.Set(i) 
    b.changed = true 
} 
func t16() { 
    s := &Sub{} 
    s.Set(1) 
    var b *Base = &s.Base 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 

Play link

注意Sub.Set()可以調用嵌入式結構的方法爲好,這感覺很像super()類型繼承,其他面向對象的語言提供。

+0

如果是這樣,那麼你是正確的,接口是要走的路。 Go沒有'is-a'類型的繼承。 – captncraig