這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
學習Go語言的過程中,會發現它的指標,地址,還有函數參數跟平常我們理解的不太一樣.
上代碼:
package main
//學習指標用法
import (
"fmt"
)
func main() {
var i int; // i 的類型是int型
var p *int; // p 的類型是[int型的指標]
i = 1; // i 的值為 1;
p = &i; // p 的值為 [i的地址]
fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p);
*p = 2; // *p 的值為 [[i的地址]的指標](其實就是i嘛),這行代碼也就等價於 i = 2
fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p);
i = 3; // 驗證我的想法
fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p);
}
這段代碼的結果是
i=1;p=0x4212e100;*p=1
i=2;p=0x4212e100;*p=2
i=3;p=0x4212e100;*p=3
你看懂了麼?再來看看下面這段代碼
package main
//學習函數參數的用法
import (
"fmt"
)
type abc struct {
v int;
}
func (a abc) aaaa (){
a.v = 1;
fmt.Printf("1:%d\n",a.v);
}
func (a *abc) bbbb (){
fmt.Printf("2:%d\n",a.v);
a.v = 2;
fmt.Printf("3:%d\n",a.v);
}
func (a *abc) cccc(){
fmt.Printf("4:%d\n",a.v);
}
func main() {
aobj := abc{} // new(abc);
aobj.aaaa();
aobj.bbbb();
aobj.cccc();
}
運行結果是
1:1
2:0
3:2
4:2
可以看到函數aaaa中,v賦值的1在函數bbbb和cccc裡消失了.為什麼呢?
細心的同學發現aaaa的[接收實體](也就是abc)是一個實參,在go語言中,實參其實就是將參數的值複製到函數裡來(參數與函數調用前在記憶體裡的地址是不一樣的).bbbb和cccc的[接收實體]是一個形參,也就是說,函數調用前後參數所在記憶體位址是一樣的!所以bbbb中,第一行的v還沒賦值所以為0,第二行的v賦值2以後在cccc中列印v的值也為2.
自己的理解 :
golang的對象方法看著和其他語言的不同,因為golang把那個隱藏的指標參數給展現出來了,即方法名前面的參數, 這樣好像用面向過程的思想去理解更好理解一些,即把方法名前面的參數也看做事方法的一個參數,事實上也正是這樣!eg:
func (t *Test) f1() {} ==== func f1(t *Test) {} 只是前面的是物件導向的寫法,而後面是面向過程的寫法,調用方式不同:
t := new(Test) t.f1() ==== t := new(Test) f1(t)
而不加*則認為是傳值了。
這裡還要提醒一句,對於[goroutin(程道)],[切片],[映射]這三種類型來說,只有形參,而且不需要加[*]號.
另外,對於參數類型是[interface]的函數參數,只有實參,而且不會將[interface]結構所包含的地址複製!