1. 程式人生 > 其它 >語言裡的指標中的值_Go 語言方法

語言裡的指標中的值_Go 語言方法

技術標籤:語言裡的指標中的值

8c7fcf93-ca4c-eb11-8da9-e4434bdf6706.svg

方法能給使用者定義的型別新增新的行為,實際上方法也是函式,只是在宣告時在關鍵字 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 語言既允許使用值,也可以使用指標來呼叫方法,不必嚴格符合接收者的型別。