Go語言中需要注意結構體方法副本傳參與指標傳參的區別
阿新 • • 發佈:2018-12-23
我們來看個例子:
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 |
執行後結果如下:
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的寫法。