golang中结构体和结构体指针的内存管理_数据存储

 

p1是结构体,p2是结构体指针。

2. 声明并赋值结构体和结构体指针



package main

import "fmt"

type Person struct {
name string
age int
}

func main() {
// 初始化结构体(创建一个结构体对象)
p1 := Person{"张三", 18}
fmt.Println(p1.name, p1.age)

// 初始化结构体指针
p2 := &Person{"李四", 28}
fmt.Println(p2.name, p2.age)

// new方法先声明结构体指针,在赋值
var p3 = new(Person)
p3.name = "王五"
p3.age = 38
fmt.Println(p3.name, p3.age)

}


  

3. 结构体赋值拷贝,结构体指针赋值引用



// 结构体指针赋值
p3 := &Person{name: "lisi", age: 25}
p4 := p3
fmt.Println(*p3, *p4)
p3.name = "王五"
fmt.Println(*p3, *p4)


  golang中结构体和结构体指针的内存管理_数据_02

 

 

4. 结构体中哪种数据类型不拷贝?

  其实本质上都拷贝了,只不过由于数据存储方式的不同,导致拷贝的有些是数据,有些是内存地址(指针)

  感觉拷贝:字符串、数组、整型等;感觉不拷贝:map、切片



package main

import "fmt"

type Address struct {
city, state string
}

type Person struct {
name string
age int
hobby [2]string
num []int
parent map[string]string
Address
}

func main() {
// 在存在结构体嵌套是,赋值会拷贝一份所有的数据
p1 := Person{
name: "liSi",
age: 18,
hobby: [2]string{"乒乓", "CF"},
parent: map[string]string{"name": "maYaNan"},
num: []int{11, 22},
Address: Address{city: "北京", state: "河北省"},
}
p2 := p1
p1.Address.city = "天津" // 嵌套的结构体拷贝了
p1.hobby[0] = "gaga" // 数组拷贝了
p1.num[0] = 88 // 切片没拷贝 (内部维护指针指向数据存储的地方)
p1.parent["name"] = "maYaJun" // map没拷贝 (内部维护指针指向数据存储的地方)
fmt.Println(p1) // {lisi 18 {天津 河北省}}
fmt.Println(p2) // {lisi 18 {北京 河北省}}
}


  注意:对于那些默认拷贝的情况,可以改变为指针类型,让数据实现同步修改。



package main

import "fmt"

type Address struct {
city, state string
}

type Person struct {
name string
age int
hobby *[2]string
num []int
parent map[string]string
Address
}

func main() {
// 在存在结构体嵌套是,赋值会拷贝一份所有的数据
p1 := Person{
name: "liSi",
age: 18,
hobby: &[2]string{"乒乓", "CF"},
parent: map[string]string{"name": "maYaNan"},
num: []int{11, 22},
Address: Address{city: "北京", state: "河北省"},
}
p2 := p1
p1.hobby[0] = "gaga" // 数组指针没有拷贝
fmt.Println(*p1.hobby) // {lisi 18 {天津 河北省}}
fmt.Println(*p2.hobby) // {lisi 18 {北京 河北省}}
}