💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] 结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存。因此必须在定义结构体并实例化后才能使用结构体字段。实例化就是根据结构体定义的格式创建一份与格式一致的内存区域。结构体实例与实例间内存是完全独立的。 ## 实例化 有四种实例化结构体的方式,其中一种是匿名结构体。 ```go package main import "fmt" // Student 学生的结构体 type Student struct { sid, age int name string course []string } func main() { // (1)基本实例化 var s1 Student fmt.Printf("s1: %#v\n", s1) // (2)取结构体的地址实例化 s2 := &Student{} fmt.Printf("s2: %#v\n", s2) // 正常指针赋值操作如下 (*s2).age = 18 fmt.Printf("s2.age: %#v\n", (*s2).age) // go语言为了方便开发者访问结构体指针成员变量简单, 使用了语法糖技术。 s2.name = "jiaxzeng" fmt.Printf("s2.name: %#v\n", s2.name) // (3)创建指针类型结构体 s3 := new(Student) fmt.Printf("s3: %#v\n", s3) // (4)匿名结构体 var user struct { Name string age int8 } fmt.Printf("user: %#v\n", user) } // 运行结果 // s1: main.Student{sid:0, age:0, name:"", course:[]string(nil)} // s2: &main.Student{sid:0, age:0, name:"", course:[]string(nil)} // s3: &main.Student{sid:0, age:0, name:"", course:[]string(nil)} // user: struct { Name string; age int8 }{Name:"", age:0} ``` > 在go语言中,结构体指针的变量可以继续使用 `.` ,这是因为go语言为了方便开发者访问结构体指针成员变量可以像访问结构体的成员变量一样简单。使用了语法糖技术。将 instance.Name 形式转换为 (*instance).Name 。 ## 初始化 ```go package main import "fmt" // Student 学生的结构体 type Student struct { sid, age int name string course []string } func main() { // 列表初始化 // 按照顺序依次赋值(所有值都需要赋值) s4 := Student{1, 22, "jiaxzeng", []string{"Golang", "Python"}} fmt.Printf("s4: %#v\n", s4) s5 := &Student{sid: 2, age: 18, name: "xiaodunan"} fmt.Printf("s5: %#v\n", s5) // 键值对初始化 // 按照key名称赋值(可以只赋值某些字段,其他字段使用类型默认值) s6 := Student{sid: 3, name: "jiaxzeng"} fmt.Printf("s6: %#v\n", s6) s7 := &Student{4, 18, "xiaodunan", []string{"nginx", "mysql"}} fmt.Printf("s7: %#v\n", s7) } // 运行结果 // s4: main.Student{sid:1, age:22, name:"jiaxzeng", course:[]string{"Golang", "Python"}} // s5: &main.Student{sid:2, age:18, name:"xiaodunan", course:[]string(nil)} // s6: main.Student{sid:3, age:0, name:"jiaxzeng", course:[]string(nil)} // s7: &main.Student{sid:4, age:18, name:"xiaodunan", course:[]string{"nginx", "mysql"}} ``` >[info] 使用这种格式初始化时,需要注意: > 1. 必须初始化结构体的所有字段。 > 2. 初始值的填充顺序必须与字段在结构体中的声明顺序一致。 > 3. 该方式不能和键值初始化方式混用。 ## 存储原理 之前我们学习过值类型和引用类型,知道值类型是变量对应的地址直接存储,而引用类型是变量对应地址存储的地址。因为结构体因为是值类型,所以s的地址与存储的第一个值的地址相同的,而后面每个成员变量的地址是连续的。 ```go type Student struct { id int name string age int8 course []string } func main() { var s = Student{1, "jiaxzeng", 18, []string{"Golang", "Python"}} fmt.Printf("s is points: %p\n", &s) fmt.Printf("s.id is points: %p\n", &s.id) fmt.Printf("s.name is points: %p\n", &s.name) fmt.Printf("s.age is points: %p\n", &s.age) fmt.Printf("s.course is points: %p\n", &s.course) } // 运行结果 // s is points: 0xc0000b8040 // s.id is points: 0xc0000b8040 // s.name is points: 0xc0000b8048 // s.age is points: 0xc0000b8058 // s.course is points: 0xc0000b8060 ``` ![](https://img.kancloud.cn/77/c4/77c487f6965db9beb1ed882be5805f76_880x530.png)