package main import ( "fmt" ) //T是M1接受者,不是實現M2接受者 //*T是M1接受者,也是M2的接受者 //因此T對象不能夠賦值給接口對象。*T能夠 //結論: // 1.結構T實現接口I時,若是想經過方法改變其屬性,則須要*T實現I全部方法: // 2.嵌套結構時,編譯器會將子結構的屬性和方法拷貝給父結構,與子結構無關係了; // 3.賦值給接口對象I1,或者接口做爲函數參數時,I1:=&T,由於是*T實現了接口I,不然報錯 type T struct { Name string } func (t T) M1(name string) { // 值傳遞,改變副本的值 t.Name = name } func (t *T) M2(name string) { // 結構體指針,修改其自己 t.Name = name } type Intf interface { M1(name string) M2(name string) } func main() { fmt.Println(`*****t1 := T{"t1"}`) t1 := T{"t1"} fmt.Println("M1以前:", t1.Name) t1.M1("name1") fmt.Println("M1以後:", t1.Name) t1.M2("name2") fmt.Println("M2以後:", t1.Name) fmt.Println(`*****t2 := &T{"t2"}`) t2 := &T{"t2"} fmt.Println("M1以前:", t2.Name) t2.M1("name1") fmt.Println("M1以後:", t2.Name) t2.M2("name2") fmt.Println("M2以後:", t2.Name) // T does not implement Intf (M2 method has pointer receiver) // var t3 Intf = t1 var t3 Intf = &t1 t1.Name = "t1" fmt.Println(`****t3 Intf = &t1`) fmt.Println("M1以前:", t1.Name) t3.M1("name1") fmt.Println("M1以後:", t1.Name) t3.M2("name2") fmt.Println("M2以後:", t1.Name) t1.Name = "t0" fmt.Println("test1 before", t1.Name) test1(&t1) fmt.Println("test1 after", t1.Name) test2(&t1) fmt.Println("test2 after", t1.Name) // 只有*S實現I,且使用接口做爲函數的參數時,須要傳遞&T,才能改變自身數據 t1.Name = "h1" test3(t1) fmt.Println(t1.Name) t1.Name = "h1" test4(&t1) fmt.Println(t1.Name) //嵌套類型 // 就是複製一份給新的結構,與原結構無關了 t1.Name = "t1" type S struct { T age int } s1 := S{T: t1, age: 12} fmt.Println(s1.Name, t1.Name) s1.M1("s1") fmt.Println(s1.Name, t1.Name) s1.M2("s2") fmt.Println(s1.Name, t1.Name) //新結構與接口 var I1 Intf = &s1 } func test1(t Intf) { t.M1("n1") } func test2(t Intf) { t.M2("n2") } func test3(t T) { t.M2("m1") } func test4(t *T) { t.M2("m2") }