Golang 偽鑽石問題

Golang 偽鑽石問題















type Reader struct{ buffer int }
type Writer struct{ buffer int }

type ReadWriter struct {
Reader
Writer
}

func main() {
var rw ReadWriter
// {Writer:{buffer:0} Reader:{buffer:0}}
fmt.Printf("%+v", rw.buffer)
// ambiguous selector rw.buffer
}

在 go 之中沒有實現真正的繼承,rw.buffer 只是一個語法糖,如果內嵌結构是匿名字段會自動提升。

要取得 buffer 就需要指定 rw.Reader.bufferrw.Writer.buffer.















type Buffer struct{ Buffer int }
type Reader struct{ Buffer }

type ReadWriter struct {
Buffer
Reader
}

func main() {
var rw ReadWriter
// {Buffer:{Buffer:0} Reader:{Buffer:{Buffer:0}}}
fmt.Printf("%+v", rw.Buffer)
// {int:0}
}

這種寫法就沒有鑽石問題,因為淺層己經有 rw.Buffer,所以 rw.Reader.buffer` 不會自動提升。

不過這種寫法非常不直觀,很容易引起混亂,查看代碼時會忘了拿的是那 Buffer。 所以這種情況下,還是盡量避免使用。