Golang中結構體和結構體指針調用的區別是什么,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
在 Go 語言中有個基本類型,開發者們稱之為結構體(struct)。是 Go 語言中非常常用的,基本定義:
type struct_variable_type struct {
member definition
member definition
...
member definition
}
簡單示例:
package main
import "fmt"
type Vertex struct {
Name1 string
Name2 string
}
func main() {
v := Vertex{"腦子進了", "煎魚"}
v.Name2 = "蒸魚"
fmt.Println(v.Name2)
}
輸出結果:
蒸魚
這部分屬于基礎知識,因此不再過多解釋。如果看不懂,建議重學 Go 語言語法基礎。
講解前置概要后,直接進入本文主題。如下例子:
type MyStruct struct {
Name string
}
func (s MyStruct) SetName1(name string) {
s.Name = name
}
func (s *MyStruct) SetName2(name string) {
s.Name = name
}
該程序聲明了一個 User
結構體,其包含兩個結構體方法,分別是 SetName1
和 SetName2
方法,兩者之間的差異就是引用的方式不同。
進一步延伸,這兩者有什么區別,什么情況下用哪種,有沒有什么注意事項?
注:很巧,我有一個朋友,當年剛上手 Go 語言時,就糾結過這個問題。
從許多小伙伴的反饋來看,這兩個例子之間的區別可能會讓人感到困惑,經常會有人糾結要不要使用 “指針”,又擔心 GC 什么的。
實際上情況沒那么復雜,看看下面的例子:
func (s MyStruct) SetName1(name string)
func (s *MyStruct) SetName2(name string)
當在一個類型上定義一個方法時,接收器(在上面的例子中是 s)的行為就像它是方法的一個參數一樣。其相當于:
func SetName1(s MyStruct, name string){
u.Name = name
}
func SetName2(s *MyStruct,name string){
u.Name = name
}
因此結構體方法是要將接收器定義成值,還是指針。這本質上與函數參數應該是值還是指針是同一個問題。
整體有以下幾個考慮因素,按重要程度順序排列:
在使用上的考慮:方法是否需要修改接收器?如果需要,接收器必須是一個指針。
在效率上的考慮:如果接收器很大,比如:一個大的結構,使用指針接收器會好很多。
在一致性上的考慮:如果類型的某些方法必須有指針接收器,那么其余的方法也應該有指針接收器,所以無論類型如何使用,方法集都是一致的。
回到上面的例子中,從功能使用角度來看:
SetName2
方法修改了 s 的字段,調用者是可以看到這些字段值變更的,因為其是指針引用,本質上是同一份。SetName1
方法來講,該方法是用調用者參數的副本來調用的,本質上是值傳遞,它所做的任何字段變更對調用者來說是看不見的。另外對于基本類型、切片和小結構等類型,值接收器是非常廉價的。
因此除非方法的語義需要指針,那么值接收器是最高效和清晰的。在 GC 方面,也不需要過度關注。出現時再解決就好了。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。