Go微服务实战
上QQ阅读APP看书,第一时间看更新

3.4.2 基本操作

很多时候我们都需要先初始化一个struct,然后将其地址引用返回给一个结构体指针变量,故而Go语言专门提供了一个new函数:


pp := new(Person)
pp.name = "Scott"

这里的pp还是指向struct的指针,但new函数已经为我们初始化了结构体,再继续为结构体的name属性赋值就不会报错了。

下面来看一个代码示例:


book/ch03/3.4/pointer/main.go
1. package main
2.
3. import "fmt"
4.
5. type Person struct {
6.     Name string
7.     Gender,Age int
8. }
9.
10. func main() {
11.     p1 := Person{Name:"Scott",Gender:1,Age:30}
12.     p2 := AddAge(p1)
13.     fmt.Println(p1)
14.     fmt.Println(p2)
15.
16.     AddAgePlus(&p1) //注意参数
17.     fmt.Println(p1)
18.
19.     pp := new(Person)
20.     AddAgePlus(pp)
21.     fmt.Println(pp)
22. }
23.
24. func AddAge(p Person) (p2 Person){
25.     p.Age += 1
26.     return p
27. }
28. func AddAgePlus(pp *Person)  {
29.     pp.Age += 1
30. }
31.
32. //以下是运行结果
33. {Scott 1 30}
34. {Scott 1 31}
35. {Scott 1 31}
36. &{ 0 1}

第5行至第8行,定义struct,注意,属性都是首字母大写,说明是包外可访问的。

第24行至第30行,定义了两个函数。AddAge使用struct作为参数,修改完成以后再返回这个struct;而AddAgePlus则会采用struct指针作为参数,把Age属性加1以后,没有返回值。

第11行至第17行是对上述两个函数的验证。先创建p1变量,然后使用p2接收AddAge函数的返回值,接着打印,参考第33行和第34行的输出结果可以发现,p1没有任何改变,而p2的Age属性加1了。这也确实证明了AddAge函数是值传递的,其函数体内的操作并没对p1产生影响。第16行调用了AddAgePlus函数,注意参数传递的是p1的地址,然后第17行接着打印p1,第35行是打印结果,可以看到p1的Age属性加1。因此,我们在使用struct的时候一定要注意指针的使用,可以提高效率。

第19行至第21行是对new函数的使用。new函数的返回值是一个结构体指针,我们用pp接收,然后调用AddAgePlus函数。注意,此时就不需要再用&取地址了,因为pp本身就是指针。第21行表示打印,第36行是打印结果,可以看到Age变为1,因为new函数初始化的时候,每个成员都用的是默认初始值。

说明

前面介绍了make函数,本节又介绍了new函数,此处将两个函数做一下对比说明。make函数用于slice、map和chan进行内存分配,它返回的不是指针,而是上面三个类型中的某一个类型本身。new函数返回初始化的类型对应的指针,new函数主要用在struct初始化中,其他场景应用较少。