語言裡的指標中的值_Go 語言方法
阿新 • • 發佈:2021-02-08
技術標籤:語言裡的指標中的值
方法能給使用者定義的型別新增新的行為,實際上方法也是函式,只是在宣告時在關鍵字 fun 和方法名之間增加了一個引數。
packagemain
import"fmt"
//使用者定義的型別/結構體
typeUserstruct{
namestring
scoreint64
}
//使用值接收者實現了一個方法
func(uUser)QueryScore(){
fmt.Printf("Query %s --> score:%d\n",u.name,u.score)
}
//使用指標接收者實現了一個方法
func(u*User)changeScore(scoreint64){
u.score=score
}
funcmain(){
//User型別的值可以用來呼叫
oscar:=User{"Oscar",100}
//使用值接收者宣告的方法
oscar.QueryScore()
//指向User型別的指標也可以用來呼叫
lisa:=&User{"Lisa",88}
//使用指標接收者宣告的方法
lisa.QueryScore()
//使用指標接收者宣告的方法
oscar.changeScore(68)
oscar.QueryScore()
//使用指標接收者宣告的方法
lisa.changeScore(77)
lisa.QueryScore()
}
- 關鍵字 func 和函式名之間的引數被稱做接收者,將函式與接收者的型別綁在一起。
- 如果一個函式有接收者,這個函式就被成為方法。
- Go 語言中有兩種型別的接收者:值接收者和指標接收者。
1、使用值接收者宣告一個方法
func(uUser)QueryScore(){}
QueryScore 方法的接收者被宣告為 User 型別的值。如果使用值接收者宣告方法,呼叫時會使用這個值的一個副本來執行。
//User型別的值可以用來呼叫
oscar:=User{"Oscar",100}
//使用值接收者宣告的方法
oscar.QueryScore()
oscar.QueryScore() 這個語法與呼叫一個包裡的函式看起來很類似,但在這個列子裡 oscar 不是包名,而是變數名。這段程式在呼叫 QueryScore 方法時,使用 oscar 的值作為接收者進行呼叫,方法 QueryScore 會接收到 oscar 的值的一個副本。
也可以使用指標來呼叫使用值接收者宣告的方法。
//指向User型別的指標也可以用來呼叫
lisa:=&User{"Lisa",88}
//使用指標接收者宣告的方法
lisa.QueryScore()
- 宣告一個名為 lisa 的指標變數,並使用指定的名字和分數地址做初始化。
- 使用 lisa 這個指標變數來呼叫 QueryScore 方法。
為了支援這種方法呼叫,Go 語言調整了指標的值, 來符合方法接收者的定義。可以認為 Go 語言執行了如下程式碼:
(*lisa).QueryScore()
- 指標被解引用為值,這樣就符合了值接收者的要求。
- QueryScore 操作的是一個副本,只不過這次操作的是從 lisa 指標指向的值的副本。
2、使用指標接收者宣告方法
//使用指標接收者實現了一個方法
func(u*User)changeScore(scoreint64){
u.score=score
}
- 接收者型別是指向 User 型別值的指標,而不是 User 型別的值。
- 當呼叫使用指標接收者宣告的方法時,這個方法會共享呼叫方法時接收者所指向的值。
//指向User型別的指標也可以用來呼叫
lisa:=&User{"Lisa",88}
//使用指標接收者宣告的方法
lisa.changeScore(77)
- 聲明瞭 lisa 指標變數。
- 使用 lisa 這個變數呼叫了 changeScore 方法。
- 一旦 changeScore 呼叫返回,這個呼叫對值做的修改也會反應在 lisa 指標所指向的值。
值接收者使用值的副本來呼叫方法,而指標接收者使用實際值來呼叫方法。
也可以使用一個值來呼叫指標接收者宣告的方法。
oscar:=User{"Oscar",100}
oscar.changeScore(68)
- 宣告一個變數 oscar 。
- 使用這個變數呼叫使用指標接收者宣告的 changeScore 方法。
為了支援這種呼叫方法,Go 語言再一次對值做了調整,使之符合函式的接收者進行呼叫。
(&oscar).changeScore(99)
- 首先引用 oscar 值得到一個指標,這樣這個指標就能夠匹配方法的接收者型別,在進行呼叫。
- Go 語言既允許使用值,也可以使用指標來呼叫方法,不必嚴格符合接收者的型別。