go语言基础结构体传参
使用struct关键字可以定义一个结构体,结构体中的成员称为结构体的字段或属性。
type Person1 struct {
Name string
Age int
}
直接定义变量,这个使用方式并没有为字段赋初始值,因此所有字段都会被自动赋予自已类型的零值,比如Name的值为空字符串"",Age的值为0。
var p1 Person1
fmt.Println(p1)
结构体与数组一样,都是值传递,比如当把数组或结构体作为实参传给函数的形参时,会复制一个副本,所以为了提高性能,一般不会把数组直接传递给函数,而是使用切片(引用类型)代替,而把结构体传给函数时,可以使用指针结构体。
指针结构体,即一个指向结构体的指针,声明结构体变量时,在结构体类型前加*号,便声明一个指向结构体的指针
var p2 *Person1
p2.Name="Hello"
使用Go内置new()函数,可以分配内存来初始化结构休,并返回分配的内存指针,因为已经初始化了,所以可以直接访问字段。
p3:=new(Person1)
p3.Name="Hello"
fmt.Println(*p3)
如果将结构体传递给函数,只是复制结构体的副本,如果在函数内修改结构体字段值,外面的结构体并不会受影响,而如果将结构体指针传给函数,则在函数中使用指针对结构体所做的修改,都会影响到指针指向的结构体。
package main
import "fmt"
type Person1 struct {
Name string
Age int
}
func main() {
var p1 Person1
fmt.Println(p1)
//var p2 *Person1
//p2.Name="Hello" //空指针 未初始化 p2为nil
p3:=new(Person1)
p3.Name="Hello"
fmt.Println(*p3)
p := Person1{Name: "John", Age: 18}
fmt.Printf("before change pointer address %p\n", &p)
noModify(p)
fmt.Println(p.Age, p.Name)
modifyPerson(&p)
fmt.Println(p.Age, p.Name)
}
func noModify(p Person1) {
fmt.Printf("noModify's pointer %p\n", &p)
p.Name = "bruce"
p.Age = 19
}
func modifyPerson(p *Person1) {
fmt.Printf("modifyPerson's pointer %p\n", p)
fmt.Printf("modifyPerson p's pointer %p\n", &p)
p.Name = "bruce"
p.Age = 19
}
运行结果如下:
{ 0}
{Hello 0}
before change pointer address 0xc00000c060
noModify's pointer 0xc00000c078
18 John
modifyPerson's pointer 0xc00000c060
modifyPerson p's pointer 0xc00000e030
19 bruce
根据运行结果可以看出结构体传参前后的内存地址是不同的,结构体指针传递给函数,指针结构体中的值就是实参结构体的地址,所以改变 形参的值实参的值也会跟着改变。