go语言基础结构体传参

 阅读大约需要1分钟

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

根据运行结果可以看出结构体传参前后的内存地址是不同的,结构体指针传递给函数,指针结构体中的值就是实参结构体的地址,所以改变 形参的值实参的值也会跟着改变。