基础用法
基础用法
package main
import "fmt"
// Student 是一个结构体类型,可以把多个字段组合在一起
type Student struct {
Name string
Age int
Score float64
}
func main() {
// 方式 1:按字段名初始化结构体
stu1 := Student{
Name: "Tom",
Age: 18,
Score: 95.5,
}
fmt.Println(stu1)
// 访问结构体字段
fmt.Println("姓名:", stu1.Name)
fmt.Println("年龄:", stu1.Age)
fmt.Println("成绩:", stu1.Score)
// 修改结构体字段
stu1.Age = 20
stu1.Score = 98
fmt.Println("修改后的 stu1:", stu1)
// 方式 2:按顺序初始化结构体
stu2 := Student{"Alice", 19, 96}
fmt.Println("stu2:", stu2)
}空结构体
:::success
这是一个非常经典的 Go 面试题,必知必会。关于这个问题,我们今天给大家了解下,以后会展开讲解的。
:::
package main
import "fmt"
// Empty 是一个空结构体,没有任何字段
type Empty struct{}
func main() {
// 创建一个空结构体变量
var e1 Empty
fmt.Println("e1 =", e1)
// 也可以直接使用字面量创建
e2 := struct{}{}
fmt.Println("e2 =", e2)
// 空结构体常用来表示“集合中的存在”
set := map[string]struct{}{
"Go": {},
"Java": {},
}
fmt.Println("set =", set)
// 判断某个值是否在集合中
_, ok := set["Go"]
fmt.Println("Go 是否存在:", ok)
// 空结构体也常用于通道通知,表示只关心信号,不关心数据内容
done := make(chan struct{}, 1)
done <- struct{}{}
<-done
fmt.Println("收到完成信号")
}结构体能否被比较
重要
这是一道非常难的题目,考察了 GO 的数据结构的底层原理。答案是,可以被比较,但是要求很苛刻。同样的,我们后续专门来聊一聊这个问题。
组合与嵌套
package main
import "fmt"
// Address 是地址结构体
type Address struct {
City string
Street string
}
// Person 是人员结构体,内部嵌套了 Address
type Person struct {
Name string
Age int
Address Address
}
// Person1 使用匿名字段组合了 Address
type Person1 struct {
Name string
Age int
Address
}
type Person2 struct{
Name string
Age int
City string
Street string
}
func main() {
// 结构体嵌套:Person 中包含一个 Address 结构体
p := Person{
Name: "Tom",
Age: 20,
Address: Address{
City: "Beijing",
Street: "Chaoyang Road",
},
}
fmt.Println("人员信息:", p)
fmt.Println("姓名:", p.Name)
fmt.Println("城市:", p.Address.City)
fmt.Println("街道:", p.Address.Street)
// 修改嵌套结构体中的字段
p.Address.City = "Shanghai"
fmt.Println("修改后的城市:", p.Address.City)
// 结构体组合:Person1 通过匿名字段组合了 Address
p1 := Person1{
Name: "Alice",
Age: 19,
Address: Address{
City: "Shenzhen",
Street: "Nanshan Road",
},
}
fmt.Println("人员信息:", p1)
// 可以直接访问被组合结构体中的字段
fmt.Println("城市:", p1.City)
fmt.Println("街道:", p1.Street)
// 也可以通过组合的结构体名访问
fmt.Println("地址信息:", p1.Address)
}带有函数的结构体
package main
import "fmt"
// Address 是地址结构体
type Address struct {
City string
Street string
}
// Person 是人员结构体,内部嵌套了 Address
type Person struct {
Name string
Age int
Address Address
}
// PrintInfo 是值接收者方法,常用于读取结构体数据
func (p Person) PrintInfo() {
fmt.Println("姓名:", p.Name)
fmt.Println("年龄:", p.Age)
fmt.Println("城市:", p.Address.City)
fmt.Println("街道:", p.Address.Street)
}
// Birthday 是指针接收者方法,可以修改结构体中的字段
func (p *Person) Birthday() {
p.Age++
}
// Person1 使用匿名字段组合了 Address
type Person1 struct {
Name string
Age int
Address
}
func main() {
// 结构体嵌套:Person 中包含一个 Address 结构体
p := Person{
Name: "Tom",
Age: 20,
Address: Address{
City: "Beijing",
Street: "Chaoyang Road",
},
}
fmt.Println("人员信息:", p)
p.PrintInfo()
// 修改嵌套结构体中的字段
p.Address.City = "Shanghai"
fmt.Println("修改后的城市:", p.Address.City)
// 调用结构体方法修改字段
p.Birthday()
fmt.Println("过生日后的年龄:", p.Age)
// 结构体组合:Person1 通过匿名字段组合了 Address
p1 := Person1{
Name: "Alice",
Age: 19,
Address: Address{
City: "Shenzhen",
Street: "Nanshan Road",
},
}
fmt.Println("人员信息:", p1)
// 可以直接访问被组合结构体中的字段
fmt.Println("城市:", p1.City)
fmt.Println("街道:", p1.Street)
// 也可以通过组合的结构体名访问
fmt.Println("地址信息:", p1.Address)
fmt.Printf("stu2:%v \n", p1)
fmt.Printf("stu2:%+v \n", p1)
fmt.Printf("stu2:%+V \n", p1)
}:::success
引申:值类型和指针类型的区别
:::
