關於golang中struct的一些理解
概述
Go語言中,struct是一個非常重要的概念,它既是一種資料型別,也可以結合方法(一種特殊的函式),構建類似於OOP的類。不多說,先上ofollow,noindex">程式碼 :
package main import ( "fmt" ) type A struct { Name string } type B struct { *A //匿名欄位,以指標方式引用結構A } type C struct { B //定義匿名欄位,以值方式引用結構B } type Interfacer interface { Get() string Set(v string) } // 構建一個結構B func NewB() *B { var a = &A{} return &B{A: a} } // 實現Interfacer中的Get func (b *B) Get() string { return b.A.Name } // 實現Interfacer中的Set func (b *B) Set(v string) { b.A.Name = v } func (b *B) Do() { if b.A.Name == "" { fmt.Println("Name is null.") return } fmt.Printf("Hello, %s.\n", b.A.Name) } var _ Interfacer = new(B) func TestImpl(i Interfacer) { i.Set("changed") fmt.Println("Get a name: " + i.Get()) } func main() { // 驗證結構B b1 := NewB() b1.Do() // 普通的賦值方法 b1.Name = "test" b1.Do() b2 := NewB() b2.Set("sail") b2.Do() // 另一種結構賦值方法 b3 := B{A: &A{Name: "oly"}} b3.Do() TestImpl(&b3) b3.Do() var c C c.A = &A{Name:"first"} c.Name = "sam" c.B.Do() TestImpl(&c.B) c.Set("other1") c.Do() c.B.Set("other2") c.B.Do() }
我的一些理解
這段程式碼中:
- 定義了A、B、C三個struct型別,一個Interfacer介面
- 結構A的作用主要是一個數據結構
- 結構B的作用相當於一個類,擁有Do()方法,並實現了Interfacer介面的Get和Set
- 結構C的作用相當於繼承於B(B也相當於繼承A)
-
結構B以指標的方式匿名引用了結構A,可以用
b.Name = "some_name"
來賦值 -
結構C以值的方式匿名引用了結構B,可以用
c.Do()
來呼叫B中的方法,由於B又匿名引用了A,還可以用c.Name = "sam"
來賦值 -
由於結構B是以
(b *B)
指標方式來實現介面Interfacer的,所以必須以指標方式來呼叫函式TestImpl(&b)
-
golang與ruby類似,介面特性是ducking type,即“如果它走起來像鴨子,叫起來像鴨子(實現了介面要的方法),它就是一隻鴨子(可以被賦值給介面的值)”。所以把&b作為引數傳入到函式
TestImpl()
中,一點問題沒有。
結論
Go語言雖然沒有類的概念,但通過struct型別、匿名欄位、方法和介面,簡單地實現了類似於OOP中類、方法、繼承等概念。