函式和方法相關的東西
函式是指不屬於任何結構體、型別的方法,也就是說,函式是沒有接收者的;而方法是有接收者的,我們說的方法要麼是屬於一個結構體的,要麼屬於一個新定義的型別的
函式
案例
這裡面add就是函式,他是獨立的
func main() {
sum := add(1, 2)
fmt.Println(sum)
}
//這個函式名稱是小寫開頭的`add`,所以它的作用域只屬於所宣告的包內使用,不能被其他包使用,如果我們把函式名以大寫字母開頭,該函式的作用域就大了,可以被其他包呼叫。
func add(a, b int) int {
return a + b
}
//函式名首字母大寫可以被其他包呼叫,相當於暴露出去了
//比如Java中,就有專門的關鍵字來宣告作用域private、protect、public等。
func Add(a, b int) int {
return a + b
}
方法
案例
//方法在定義的時候,會在func和方法名之間增加一個引數,這個引數就是接收者,這樣我們定義的這個方法就和接收者繫結在了一起,稱之為這個接收者的方法。
//在其他語言中可以理解為,物件方法
type person struct {
name string
}
//(p person),這個就是接收者
func (p person) String() string{
return "the person name is "+p.name
}
接收者操作
name string
}
func (receiver person) String() string {
return "操作人的名字是 "+ receiver.name
}
func main() {
p:=person{name:"董雷"}
fmt.Println(p.String())
}
//返回資料
操作人的名字是 董雷
接受者型別
值接收者
type person struct {
name string
}
func (receiver person) String() string {
return "操作人的名字是 "+ receiver.name
}
//因為是值接收者,所以modify並不為影響裡面的值
func (receiver person) modify(){
receiver.name = "董華"
}
func main() {
p:=person{name:"董雷"}
p.modify() //值接收者,修改無效
fmt.Println(p.String())
}
//返回結果
操作人的名字是 董雷
指標接收者
如果我們使用一個指標作為接收者,那麼就會其作用了,因為指標接收者傳遞的是一個指向原值指標的副本,指標的副本,指向的還是原來型別的值,所以修改時,同時也會影響原來型別變數的值。
type person struct { name string } func (receiver person) String() string { return "操作人的名字是 "+ receiver.name } //這個時候因為是指標接收者,所以會修改以前的值 func (receiver *person) modify(){ receiver.name = "董華" } func main() { p:=person{name:"董雷"} p.modify() //指標接收者,修改有效 fmt.Println(p.String()) } //返回結果 操作人的名字是 董華 //main這種方式可以 func main() { p:=person{name:"董雷"} //這樣也是可以的。如果我們沒有這麼強制使用指標進行呼叫,Go的編譯器自動會幫我們取指標,以滿足接收者的要求。 (&p).modify() //指標接收者,修改有效 fmt.Println(p.String()) } //返回資料 操作人的名字是 董華
總之,方法的呼叫,既可以使用值,也可以使用指標,我們不必要嚴格的遵守這些,Go語言編譯器會幫我們進行自動轉義的,這大大方便了我們開發者。
總結
在呼叫方法的時候,傳遞的接收者本質上都是副本,只不過一個是這個值副本,一是指向這個值指標的副本。指標具有指向原有值的特性,所以修改了指標指向的值,也就修改了原有的值。我們可以簡單的理解為值接收者使用的是值的副本來呼叫方法,而指標接收者使用實際的值來呼叫方法。
多值返回
就是返回多個值而已,沒啥額外需要說明的
func add(a, b int) (int, error) { return a + b, nil }
可變引數
這個使用場景還是比較多的
參考案例1
參考案例2
本作品採用《CC 協議》,轉載必須註明作者和本文連結