匿名结构体
在定义变量时将类型指定为结构体的结构,此时叫匿名结构体。匿名结构体常用于初始化一次结构体变量的场景,例如项目配置。
package main
import "fmt"
func main() {
// 匿名结构体
var u struct {
ID int
Name string
}
fmt.Printf("%T\n", u)
fmt.Printf("%#v\n", u)
// 访问元素和修改元素
fmt.Println(u.ID)
u.ID = 1
u.Name = "test"
fmt.Printf("%#v\n", u)
// 匿名结构体简短声明并初始化
u1 := struct {
ID int
Name string
}{1, "wpfs"}
fmt.Printf("%#v\n", u1)
}
匿名嵌入
结构体匿名嵌入是指将已定义的结构体名直接声明在新的结构体中,从而实现对以后已有类型的扩展和修改。
在访问和修改嵌入结构体的属性值时,可以通过对象名.结构体名称.属性名的方式进行访问和修改,结构体名称可以省略(匿名成员有一个隐式的名称),因此不能嵌套两个相同名称的结构体。
当被嵌入结构体和嵌入结构体有相同的属性名时,在访问和修改嵌入结构体成员的属性值时不能省略结构体名称。
package main
import "fmt"
// 定义地址结构体
type Address struct {
Region string
Street string
Number string
}
// 定义用户结构体
type User struct {
ID int
Name string
Addr Address
}
type Employee struct {
// 匿名嵌入 访问时可以省略名称
// 命名重复,如Name在User中也有。会先在当前对象里面找
User
Salary float64
Name string
}
func main() {
// 声明结构体
var u1 Employee
fmt.Printf("%T,%#v\n", u1, u1)
// 简短声明并初始化结构体
u2 := Employee{
User: User{
ID: 2,
Name: "u2",
Addr: Address{
Region: "北京市",
Street: "霍营",
Number: "002",
},
},
Salary: 12,
}
fmt.Printf("%T,%#v\n", u2, u2)
// 属性的访问和修改
fmt.Println(u2.User.Name)
fmt.Println(u2.User.Addr.Region)
u2.User.Addr.Region = "大道"
fmt.Printf("%T,%#v\n", u2, u2)
fmt.Println(u2.Name)
fmt.Println(u2.Addr.Street)
u2.Addr.Number = "0002"
u2.Name = "wpf"
fmt.Printf("%T,%#v\n", u2, u2)
}
多个元素相同的嵌入,必须指定全路径访问
package main
import "fmt"
// 定义Address结构体
type Address struct {
Region string
Street string
No string
}
// 定义User结构体
type User struct {
ID int
Name string
Addr Address //命名结构体嵌入
}
// 定义Company结构体
type Company struct {
ID int
Name string
Addr Address
Salary float64
}
// 定义Employee结构体
type Employee struct {
User //匿名结构体嵌入
Company
Salary float64
Name string
}
func main() {
// 声明结构体
var u Employee
fmt.Printf("%T,%#v\n", u, u)
//匿名嵌入的结构体属性相同时,必须使用全路径
u.Company.Name = "companyname"
u.User.Name = "wpfs"
fmt.Println(u.Company.Name)
fmt.Println(u.User.Name)
}
指针类型嵌入
结构体嵌入(命名&匿名)类型也可以为结构体指针
命名型
package main
import "fmt"
// 定义Address结构体
type Address struct {
Region string
Street string
Number string
}
// 定义User结构体
type User struct {
ID int
Name string
Addr *Address // 嵌入命名结构体指针类型
}
func main() {
//声明结构体
var u1 User
fmt.Printf("%#v\n", u1)
u2 := User{
ID: 1,
Name: "wpfs",
Addr: &Address{"北京", "霍营", "01"},
}
fmt.Printf("%#v\n", u2)
fmt.Printf("%#v\n", u2.Addr)
// 2种访问指针类型的元素和修改的方式
(*u2.Addr).Number = "02"
fmt.Printf("%#v\n", u2.Addr)
u2.Addr.Number = "03"
fmt.Printf("%#v\n", u2.Addr)
}
匿名型
package main
import "fmt"
// 定义Address结构体
type Address struct {
Region string
Street string
Number string
}
// 定义User结构体
type User struct {
ID int
Name string
Addr Address
}
// 定义Employee结构体
type Employee struct {
*User // 匿名嵌入指针类型
Salary float64
Name string
}
func main() {
//声明结构体
var u Employee
fmt.Printf("%#v\n", u)
//简短声明并初始化结构体
u1 := Employee{
User: &User{
ID: 1,
Name: "wpfs",
Addr: Address{"北京", "霍营", "01"},
},
Salary: 1024,
Name: "eeu",
}
fmt.Printf("%#v\n", u1)
//访问与修改元素
fmt.Printf("%#v\n", u1.Name)
fmt.Printf("%#v\n", u1.Addr)
fmt.Printf("%#v\n", u1.User.ID)
fmt.Printf("%#v\n", u1.User.Name)
fmt.Printf("%#v\n", u1.User.Addr)
u1.User.ID = 2
fmt.Printf("%#v\n", u1.User.ID)
}