轉到函數的參數是按值傳遞。
首先,讓我們放棄您示例中不相關的部分,以便我們可以輕鬆地看到您僅僅通過值傳遞參數。例如,
package main
import "fmt"
func byval(q *int) {
fmt.Printf("3. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
*q = 4143
fmt.Printf("4. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
q = nil
}
func main() {
i := int(42)
fmt.Printf("1. main -- i %T: &i=%p i=%v\n", i, &i, i)
p := &i
fmt.Printf("2. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
byval(p)
fmt.Printf("5. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
fmt.Printf("6. main -- i %T: &i=%p i=%v\n", i, &i, i)
}
輸出:
1. main -- i int: &i=0xf840000040 i=42
2. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=42
3. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=42
4. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=4143
5. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=4143
6. main -- i int: &i=0xf840000040 i=4143
在功能main
,i
是在存儲器位置(&i
)0xf800000040
與初始值(i
)42
一個int
變量。
在功能main
,p
是一個指針,指向在存儲位置(&p
)0xf8000000f0
用一個值(p
= &i
)0xf800000040
它指向一個int
值(*p
= i
)42
一個int
變量。
在功能main
,byval(p)
是一個函數調用,它在存儲位置(&q
)0xf8000000d8
的值(p
= &i
)在存儲位置(&p
)0xf8000000f0
參數的0xf800000040
分配給功能byval
參數q
。換句話說,爲byval
參數q
分配了存儲空間,併爲其分配了參數p
的main
byval
值; p
和q
的值最初是相同的,但變量p
和q
是不同的。
在功能byval
,使用指針q
(*int
),這是指針p
(*int
)的副本,整數*q
(i
)被設定爲一個新的int值4143
。在返回之前結束。指針q
設置爲nil
(零值),這對p
沒有影響,因爲q
是副本。
在功能main
,p
是一個指針,指向在存儲位置(&p
)0xf8000000f0
用一個值(p
= &i
)0xf800000040
指向新int
值(*p
= i
)4143
一個int
變量。
在功能main
,i
是在存儲器位置(&i
)0xf800000040
與最終值(i
)4143
一個int
變量。
在您的例子中,函數main
可變s
用作的一個參數函數gotest
呼叫不是一樣的功能gotest
參數s
。它們具有相同的名稱,但具有不同範圍和內存位置的不同變量。函數參數s
隱藏函數調用參數s
。這就是爲什麼在我的例子中,我分別命名參數和參數變量p
和q
以強調這種差異。
在您的例子,(&s
)0x4930d4
是用於功能main
可變s
被用作一個參數的函數調用gotest(s, done)
的存儲器位置的地址,並且0x4974d8
是的存儲器位置的該函數的地址gotest
參數s
。如果在功能gotest
的末尾設置參數s = nil
,則它對main
中的變量s
沒有影響; s
在main
和s
在gotest
是不同的存儲位置。根據類型,&s
是**Something
,s
是*Something
,並且*s
是Something
。 &s
是指向(存儲器位置的地址)s
的指針,它是指向(存儲器位置的地址)類型Something
的匿名變量的指針。根據數值,main.&s != gotest.&s
,main.s == gotest.s
,main.*s == gotest.*s
和main.s.number == gotest.s.number
。
你應該採取mkb的賢者的建議,並停止使用println(&s)
。使用fmt
包,例如,
fmt.Printf("%v %p %v\n", &s, s, *s)
指針具有相同的值時,它們指向相同的內存位置;當指針指向不同的內存位置時,指針具有不同的值。
你不應該使用內置的println而是用一些適當從FMT包:HTTP:// golang .org/doc/go_spec.html#引導 – mkb 2011-02-09 02:30:28