1. 程式人生 > >Go語言中需要注意結構體方法副本傳參與指標傳參的區別

Go語言中需要注意結構體方法副本傳參與指標傳參的區別

我們來看個例子:

1234567891011121314151617181920212223242526272829 packagemainimport("fmt")typeBstruct{Name string}func(bB)Test1(){fmt.Printf("Test1 addr:%p\n",&b)fmt.Printf("Test1 name:%s\n",b.Name)b.Name="john"}func(b *B)Test2(){fmt.Printf("Test2 addr:%p\n",b)fmt.Printf
("Test2 name:%s\n",b.Name)b.Name="john"}funcmain(){b:=B{}b.Test1()b.Test1()b.Test2()b.Test2()}

執行後結果如下:

12345678 Test1 addr:0xc42000e1e0Test1 name:Test1 addr:0xc42000e1f0Test1 name:Test2 addr:0xc42000e1d0Test2 name:Test2 addr:0xc42000e1d0Test2 name:john

可以看到Test1中打印出b結構體的地址在變化,而Test2中沒有變化,這說明每一次Test1的呼叫,都是傳入的結構體b的一個副本(拷貝),當在Test1中對內部變數的任何改動,都將會失效(因為下一次訪問的時候傳入的是b結構體新的副本)。而Test2方法作為指標傳參時,每一次傳入的都是b結構體的指標,指向的是同一個結構體,因此地址沒有變化,且對內部變數做改動時,都是改動的b結構體內容。

在Go語言中的這個差別可能是對OOP設計的一個坑,在Go語言中要想實現OOP的設計,在進行方法封裝時,都採用Test2的寫法。