在學習 go 語言結構時,遇到這樣一個問題:
- 通過自建構造函數,返回一個結構體變量,或者返回一個結構體指針,他們的區別是什麼?
- 因爲二者都可以讓我們生成我們所需要的結構體,那爲什麼還要去使用返回結構體指針的構造函數呢?
對於此疑問,我做了如下實驗:
type person struct {
name string
age int
}
// newPerson 返回一個結構體變量
func newPerson(name string,age int) person{
ret := person{
name: name,
age: age,
}
// 在創建結構體時,返回其內存地址
fmt.Printf("%p\n",&ret)
return ret
}
// newPerson2 返回一個結構體指針
func newPerson2(name string,age int) *person{
ret := &person{
name: name,
age: age,
}
// 在創建結構體指針時,返回他儲存的結構體的地址
fmt.Printf("%p\n",ret)
return ret
}
func main(){
p1 := newPerson("張三", 1)
fmt.Printf("%p\n", &p1)
p2 := newPerson2("李四", 2)
fmt.Printf("%p\n", p2)
}
F:\Go_project\my_go\student_manager>go
run struck_poniter.go
// 以下是調用構造函數newPerson時,返回的結構體變量的地址
0xc000096460
// 以下是調用構造函數newPerson時,創建的結構體實例的地址
0xc000096440
// 以下是調用構造函數newPerson2時,返回的結構體指針的地址
0xc0000964a0
// 以下是調用構造函數newPerson2時,創建的結構體指針的地址
0xc0000964a0
由此可得出結論
使用構造函數創建 結構實例時:
兩點:1.go
語言中函數的傳參時值的傳遞,2.go
語言中的結構體
時值類型的
如果構造函數返回的是一個結構體變量,在創建結構體實例時,是將構造函數中生成的結構體變量的值傳給對應新創建的結構體變量,在上例字中對應的就是 p1
,此時內存中就有值相同的兩份結構體
如果構造函數返回的是一個結構體指針(newPerson2
函數),構造函數最後是將改函數創建的結構體對應的地址傳給了我們創建的實例p2
,注意,此時p2
是一個結構體指針
,這種創建方式,內存中只有一份結構體,對內存的消耗小
試想,如果我們的結構體中含有很多個成員,並且在我們的程序中,通過返回值是結構體變量的構造函數創建了很多個結構體,此時構造函數會生成對應的結構體,並分別將至複製給對一個你的結構體實例,這樣會產生很多不必要的內存開銷,此時如果使用返回值是結構體指針的構造函數來進行結構體實例的創建,就會避免
以上就是我在學習go
時,對go 自建構造函數,返回值是結構體變量,或者結構體指針的原因的一個理解