Golang中結(jié)構(gòu)體和結(jié)構(gòu)體指針調(diào)用的區(qū)別是什么,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
創(chuàng)新互聯(lián)公司主營新洲網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶App定制開發(fā),新洲h5微信平臺小程序開發(fā)搭建,新洲網(wǎng)站營銷推廣歡迎新洲等地區(qū)企業(yè)咨詢
在 Go 語言中有個基本類型,開發(fā)者們稱之為結(jié)構(gòu)體(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)
}
輸出結(jié)果:
蒸魚
這部分屬于基礎(chǔ)知識,因此不再過多解釋。如果看不懂,建議重學(xué) Go 語言語法基礎(chǔ)。
講解前置概要后,直接進入本文主題。如下例子:
type MyStruct struct {
Name string
}
func (s MyStruct) SetName1(name string) {
s.Name = name
}
func (s *MyStruct) SetName2(name string) {
s.Name = name
}
該程序聲明了一個 User
結(jié)構(gòu)體,其包含兩個結(jié)構(gòu)體方法,分別是 SetName1
和 SetName2
方法,兩者之間的差異就是引用的方式不同。
進一步延伸,這兩者有什么區(qū)別,什么情況下用哪種,有沒有什么注意事項?
注:很巧,我有一個朋友,當年剛上手 Go 語言時,就糾結(jié)過這個問題。
從許多小伙伴的反饋來看,這兩個例子之間的區(qū)別可能會讓人感到困惑,經(jīng)常會有人糾結(jié)要不要使用 “指針”,又擔(dān)心 GC 什么的。
實際上情況沒那么復(fù)雜,看看下面的例子:
func (s MyStruct) SetName1(name string)
func (s *MyStruct) SetName2(name string)
當在一個類型上定義一個方法時,接收器(在上面的例子中是 s)的行為就像它是方法的一個參數(shù)一樣。其相當于:
func SetName1(s MyStruct, name string){
u.Name = name
}
func SetName2(s *MyStruct,name string){
u.Name = name
}
因此結(jié)構(gòu)體方法是要將接收器定義成值,還是指針。這本質(zhì)上與函數(shù)參數(shù)應(yīng)該是值還是指針是同一個問題。
整體有以下幾個考慮因素,按重要程度順序排列:
在使用上的考慮:方法是否需要修改接收器?如果需要,接收器必須是一個指針。
在效率上的考慮:如果接收器很大,比如:一個大的結(jié)構(gòu),使用指針接收器會好很多。
在一致性上的考慮:如果類型的某些方法必須有指針接收器,那么其余的方法也應(yīng)該有指針接收器,所以無論類型如何使用,方法集都是一致的。
回到上面的例子中,從功能使用角度來看:
SetName2
方法修改了 s 的字段,調(diào)用者是可以看到這些字段值變更的,因為其是指針引用,本質(zhì)上是同一份。SetName1
方法來講,該方法是用調(diào)用者參數(shù)的副本來調(diào)用的,本質(zhì)上是值傳遞,它所做的任何字段變更對調(diào)用者來說是看不見的。另外對于基本類型、切片和小結(jié)構(gòu)等類型,值接收器是非常廉價的。
因此除非方法的語義需要指針,那么值接收器是最高效和清晰的。在 GC 方面,也不需要過度關(guān)注。出現(xiàn)時再解決就好了。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。