Go 类型-结构体
Overview ⚡️
- 结构体名,大小写都可,用于区分可见性
- 列表形式初始化结构体,必须将所有字段都出列出
- Go 语言没有默认实现构造函数,原因主要是为了保持语言的简洁性、灵活性和明确性
- 指针访问结构体的字段,等价直接访问结构体
- 理解“接收者”,在 Go 语言中,方法调用类似于向一个类型实例发送一条消息,而实例则是接收这条消息并执行相应的方法。因此,实例被称为“接收者”
- 当你将切片传递给函数时,实际上传递的是对底层数组的引用。这意味着在函数内部对切片元素的修改会反映到原切片上
结构体说明
- 类型名:标识自定义结构体的名称,在同一个包内不能重复。
- 字段名:表示结构体字段名。结构体中的字段名必须唯一。
- 字段类型:表示结构体字段的具体类型。
在 Go 语言中,结构体(struct)是用户定义的类型。它由一组字段(属性)组成,每个字段可以是不同的类型。结构体可以用来组合数据,并且可以定义方法。
自己的理解:结构体是自定义的组合类型, 方法分为两类:读和修改
定义结构体类型
type Person struct {
Name string
Age int
}
创建结构体实例
p := Person{Name: "Alice", Age: 30}
fmt.Println(p) // 输出: {Alice 30}
使用值接收者的方法
你可以为结构体定义方法:
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}
使用指针接收者的方法
如果你希望方法修改结构体的字段,可以使用指针接收者:
func (p *Person) HaveBirthday() {
p.Age++
}
结构体嵌套
结构体可以包含其他结构体:
type Address struct {
City string
Street string
}
type Person struct {
Name string
Age int
Address Address
}
示例
综合以上内容的示例:
package main
import "fmt"
type Address struct {
City string
Street string
}
type Person struct {
Name string
Age int
Address Address
}
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}
func (p *Person) HaveBirthday() {
p.Age++
}
func main() {
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
City: "New York",
Street: "5th Avenue",
},
}
p.Greet() // 输出: Hello, my name is Alice and I am 30 years old.
p.HaveBirthday()
fmt.Println(p.Age) // 输出: 31
}
总结
在 Go 语言中,结构体是用户定义的类型。通过定义结构体和方法,你可以创建复杂的数据结构和行为。
同名字段的情况
非指针类型同名字段

指针类型匿名字段

指针访问结构体的字段,等价直接访问结构体
在 Go 语言中,当你存储结构体的地址到映射(map)中时,你实际上存储的是指向该结构体的指针。通过这个指针,你可以访问结构体的字段。
结构体指针的使用
在 Go 中,结构体指针允许你通过指针访问结构体的字段,就像你直接访问结构体一样。假设你有一个 student 结构体和一个指向它的指针 *student,你可以通过指针直接访问结构体的字段。
示例解释
假设你有如下代码:
package main
import "fmt"
type student struct {
name string
age int
}
func main() {
m := make(map[string]*student)
stus := []student{
{name: "pprof.cn", age: 18},
{name: "测试", age: 23},
{name: "博客", age: 28},
}
for _, stu := range stus {
s := stu // 创建一个新的变量 s
m[s.name] = &s
}
for k, v := range m {
fmt.Println(k, "=>", v.name, v.age)
}
}