package main
import "fmt"
func main() {
var i1 = 5
fmt.Printf("An integer: %d, its location in memory: %p\n", i1, &i1)
var intP *int
intP = &i1
fmt.Printf("The value at memory location %p is %d\n", intP, *intP)
}
package main
import "fmt"
func main() {
s := "good bye"
var p *string = &s
*p = "ciao"
fmt.Printf("Here is the pointer p: %p\n", p) // prints address
fmt.Printf("Here is the string *p: %s\n", *p) // prints string
fmt.Printf("Here is the string s: %s\n", s) // prints same string
}
Go 默認(rèn)使用按值傳遞來傳遞參數(shù),也就是傳遞參數(shù)的副本凹髓。
函數(shù)接收參數(shù)副本之后烁登,在使用變量的過程中可能對(duì)副本的值進(jìn)行更改,但不會(huì)影響到原來的變量蔚舀。
如果你希望函數(shù)可以直接修改參數(shù)的值饵沧,而不是對(duì)參數(shù)的副本進(jìn)行操作蚀之,你需要將參數(shù)的地址(變量名前面添加&符號(hào),比如 &variable)傳遞給函數(shù)捷泞,這就是按引用傳遞,比如Function(&arg1)
寿谴,此時(shí)傳遞給函數(shù)的是一個(gè)指針锁右。如果傳遞給函數(shù)的是一個(gè)指針,指針的值(一個(gè)地址)會(huì)被復(fù)制讶泰,但指針的值所指向的地址上的值不會(huì)被復(fù)制咏瑟;我們可以通過這個(gè)指針的值來修改這個(gè)值所指向的地址上的值。(譯者注:指針也是變量類型痪署,有自己的地址和值码泞,通常指針的值指向一個(gè)變量的地址。所以狼犯,按引用傳遞也是按值傳遞余寥。)
幾乎在任何情況下,傳遞指針(一個(gè)32位或者64位的值)的消耗都比傳遞副本來得少悯森。
在函數(shù)調(diào)用時(shí)宋舷,像切片(slice)、字典(map)瓢姻、接口(interface)祝蝠、通道(channel)這樣的引用類型都是默認(rèn)使用引用傳遞(即使沒有顯式的指出指針)。
defer僅在函數(shù)返回時(shí)才會(huì)執(zhí)行幻碱,在循環(huán)的結(jié)尾或其他一些有限范圍的代碼內(nèi)不會(huì)執(zhí)行绎狭。
命名返回值作為結(jié)果形參(result parameters)被初始化為相應(yīng)類型的零值,
當(dāng)需要返回的時(shí)候褥傍,我們只需要一條簡(jiǎn)單的不帶參數(shù)的return語句儡嘶。
func getX2AndX3_2(input int) (x2 int, x3 int) {
? x2 = 2 * input
? x3 = 3 * input
? // return x2, x3
? return
}
如果函數(shù)的最后一個(gè)參數(shù)是采用 `...type` 的形式,那么這個(gè)函數(shù)就可以處理一個(gè)變長(zhǎng)的參數(shù)摔桦,
這個(gè)長(zhǎng)度可以為 0社付,這樣的函數(shù)稱為變參函數(shù)。
func Greeting(prefix string, who ...string)
Greeting("hello:", "Joe", "Anna", "Eileen")
在 Greeting 函數(shù)中邻耕,變量 who 的值為 []string{"Joe", "Anna", "Eileen"}