Fork me on GitHub

Golang之旅35-struct4

Struct-two

创建和访问结构体字段

  • var person Person
  • var person Person = Person{}
  • var person *Person = new(Person)
  • Var person *Person = &Person{}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main
import "fmt"

type Person struct{
Name string
Age int
}

func main(){
// 方式1
var person Person
person.Name = "小明"
person.Age = 18

// 方式2
p2 := Person{"小明", 18}

// 方式 2 变形
//p2 := Person{}
//p2.Name = "小明"
//p2.Age = 18
fmt.Println(p2)

// 方式3
// p3 是一个指针
// 标准方式:(*p3).Name = "小红";等价于p3.Name = "小红",底层处理过
var p3 *Person=new(Person)
(*p3).Name = "小红"
p3.Name = "张三"

(*p3).Age = 20
p3.Age = 25
fmt.Println(p3) // Name输出是张三,Age输出是25

// 方式4
// var p4 *Person = &Person{"小明", 26}
var p4 *Person = &Person{}
(*p4).Name = "李四" // 标准方式
p4.Name = "王五" // 底层处理过
(*p4).Age = 22
}

结构体内存分配机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main
import "fmt"

type Person struct {
Name string
Age int
}

func main(){
var p1 Person
p1.Age = 18
p1.Name = "小明"
var p2 *Person = &p1 // 重点理解代码

// 输出p1、p2的地址
fmt.Printf("p1的地址是%p \n", &p1)
fmt.Printf("p2的地址是%p p2的值是%p \n", &p2, p2)

fmt.Println((*p2).Age)
fmt.Println(p2.Age)
p2.Name = "Tom"

fmt.Println(p2.Name, p1.Name) // Tom Tom
fmt.Println((*p2).Name, p1.Name) // Tom Tom
}

  • p2有着自己的值,该值就是p1的内存地址
  • p2也有着自己的内存地址

结构体使用

  • 结构体中的所有字段在内存中是连续的
  • 指针本身的地址是连续的,但是指向的地址未必是连续的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import "fmt"

type Point struct{
x int
y int
}

type Rect struct{
leftup, rightdown Point // 嵌套结构体
}

type Rect2 struct{
leftup, rightdown *Point // 嵌套指针结构体
}

func main(){
r1 := Rect{Point{1,2}, Point{3,4}}
fmt.Printf(&r1.leftup.x, &r1.leftup.y, &r1.rightdown.x,&r1.rightdown.y)

r2 := Rect2{&Point{10,20}, &Point{30,40}}
fmt.Printf(&r2.leftup, &r2.rightdown)

}
  • 结构体是用户自定义的数据类型,结构体的字段名、个数和类型需要完全相同才能转换。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import "fmt"

type A struct{
Num int
}

type B struct{
Num int
}

func main(){
var a A
var b B
a = A(b) // 转换:结构体的字段要完全相同
// a = b 报错
fmt.Println(a, b)
}
  • 结构体进行type重新定义,相当于是取别名,Golang认为是新的数据类型,但是可以强转

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type Student struct {
    Name string
    Age int
    }

    type Stu Student // 取别名
    func main(){
    var stu1 Student
    var stu2 Stu
    stu2 = Stu(stu1) // 强制转换
    //stu2 = stu1 报错
    fmt.Println(stu1, stu2)
    }
  • 结构体的每个字段写上一个tag,通过反射机制进行获取,常见的场景是序列化和反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import (
"fmt"
"encoding\json"
)

type Monster struct{
Name string `json:"name"` // 打上tag
Age int `json:"age"`
Skill string `json:"skill"`
}

func main(){
//1. 创建一个Monster 变量
monster := Monster{"牛魔王", 500, "芭蕉扇~"}

//2. 将monster变量序列化为一个json格式字符串
// json.Marshal 函数中使用到了反射机制
jsonstr, err := json.Marshal(monster)
if err != nil{
fmt.Println(err)
}
fmt.Println("jsonstr", string(jsonstr))
}

4668 3643 45

本文标题:Golang之旅35-struct4

发布时间:2019年11月15日 - 11:11

原始链接:http://www.renpeter.cn/2019/11/15/Golang%E4%B9%8B%E6%97%8535-struct4.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea