Go通關05:函式和方法的不同之處!
阿新 • • 發佈:2021-08-04
函式
函式宣告
func funcName(params) result {
body
}
- 關鍵字 func 用於宣告一個函式
- funcName 函式名
- params 函式的引數
- result 是函式的返回值,可以返回多個返回值,如果沒有可以省略。
- body 函式體
示例
1.
- a、b形參型別一致,可以省略其中一個型別的宣告
func sum (a, b int) {
return a + b
}
2.多值返回
- 返回值的部分型別定義需要小括號括起來。
func sum (a, b int) (int,error) { if a <0 || b <0 { return 0, errors.New("a或b不能是負數") } return a + b, nil }
3.命名引數返回
- 函式中給命名返回引數賦值,相當於函式有了返回值,所以可以忽略 return 後要返回的值了。
func sum (a, b int) (sum int,err error) {
if a <0 || b <0 {
return 0, errors.New("a或b不能是負數")
}
sum = a + b
err = nil
return
}
4.可變引數
- 函式的引數是可變的
- 定義可變引數,只要在引數型別前加三個點 ... 即可
- 可變引數的型別其實就是切片,下面示例中 params 的引數型別是 []int
func sum(params ...int) int { sum := 0 for _, i := range params { sum += i } return sum }
包級函式
- 函式都會從屬於一個包,我們自定義的函式屬於 main 包。Println 函式屬於 fmt 包。
- 想要呼叫其他包內的函式,那麼那個函式名稱首字母要大寫,使其作用域變為公有的。
- 函式首字母小寫,只能在同一個包中被呼叫
匿名函式和閉包
匿名函式就是沒有名稱的函式。
func main(){
//注意,sum 只是一個函式型別的變數,不是函式名字
sum := func(a, b int) int {
return a + b
}
fmt.Println(sum(1, 2)) // 3
}
匿名函式可以在函式中進行巢狀,這個匿名函式稱為內部函式,內部函式可以使用外部函式的變數,這種方式就是閉包。
func main (){
sm := sum()
fmt.Println(sum())
fmt.Println(sum())
fmt.Println(sum())
}
func sum () func() int{
i := 0
return func ()int{
i++
return i
}
}
//結果為:
1
2
3
由於閉包函式,sum 函式返回一個匿名函式,匿名函式持有外部函式 sum 的變數 i,所以在main函式中,每次呼叫 sum(),i的值就會 +1。
在 Go 語言中,函式也是一種型別,可以作為函式型別的變數、引數、或者一個函式的返回值。
方法
方法和函式類似,不同之處就是方法必須有一個接收者,這個接收者是一個“類”(型別),這樣這個方法就算屬於這個“類”。
type Name string
func (n Name)String(){
fmt.Println("name is ", n)
}
- 示例中 String() 就是 Name 這個型別的方法
- 接收者需要加在 func 和方法名之間,使用()
- 接收者: (變數,型別)
使用:
func main(){
name := Name("無塵")
name.String()
}
//出處
name is 無塵
值型別接收者、指標型別接收者
方法的接收者可以使用值型別(例如上面示例)或者指標型別。
如果接收者是指標,那麼對指標的修改是有效的:
func (n *Name) Modify(){
*n = Name("wucs")
}
func main(){
name := Name("無塵")
name.String()
name.Modify()
name.String()
}
//輸出
name is 無塵
name is wucs
注意:在呼叫方法時,傳遞的接收者實質上都是副本,只不過一個是值副本,一個是指向這個值的指標的副本。指標指向原有值,所以修改指標指向的值,也就修改了原有值。
方法的呼叫者,可以是值,也可以是指標((&name).Modify()),Go 語言會自動轉義,我們無需關心。
方法表示式
方法可以賦值給變數
name := Name("無塵")
//方法賦值給變數,方法表示式
n = Name.String
//要傳一個接收者name進行呼叫
n(name)
無論方法是否有引數,通過方法表示式呼叫,第一個引數必須是接收者,然後才是方法自身的引數。