匿名結(jié)構(gòu)體
在定義變量時(shí)將類型指定為結(jié)構(gòu)體的結(jié)構(gòu)颂暇,此時(shí)叫匿名結(jié)構(gòu)體。匿名結(jié)構(gòu)體常用于初始化一次結(jié)構(gòu)體變量的場(chǎng)景但惶,例如項(xiàng)目配置耳鸯。
package main
import "fmt"
func main() {
// 匿名結(jié)構(gòu)體
var u struct {
ID int
Name string
}
fmt.Printf("%T\n", u)
fmt.Printf("%#v\n", u)
// 訪問(wèn)元素和修改元素
fmt.Println(u.ID)
u.ID = 1
u.Name = "test"
fmt.Printf("%#v\n", u)
// 匿名結(jié)構(gòu)體簡(jiǎn)短聲明并初始化
u1 := struct {
ID int
Name string
}{1, "wpfs"}
fmt.Printf("%#v\n", u1)
}
匿名嵌入
結(jié)構(gòu)體匿名嵌入是指將已定義的結(jié)構(gòu)體名直接聲明在新的結(jié)構(gòu)體中,從而實(shí)現(xiàn)對(duì)以后已有類型的擴(kuò)展和修改膀曾。
在訪問(wèn)和修改嵌入結(jié)構(gòu)體的屬性值時(shí)县爬,可以通過(guò)對(duì)象名.結(jié)構(gòu)體名稱.屬性名的方式進(jìn)行訪問(wèn)和修改,結(jié)構(gòu)體名稱可以省略(匿名成員有一個(gè)隱式的名稱)添谊,因此不能嵌套兩個(gè)相同名稱的結(jié)構(gòu)體财喳。
當(dāng)被嵌入結(jié)構(gòu)體和嵌入結(jié)構(gòu)體有相同的屬性名時(shí),在訪問(wèn)和修改嵌入結(jié)構(gòu)體成員的屬性值時(shí)不能省略結(jié)構(gòu)體名稱斩狱。
package main
import "fmt"
// 定義地址結(jié)構(gòu)體
type Address struct {
Region string
Street string
Number string
}
// 定義用戶結(jié)構(gòu)體
type User struct {
ID int
Name string
Addr Address
}
type Employee struct {
// 匿名嵌入 訪問(wèn)時(shí)可以省略名稱
// 命名重復(fù)耳高,如Name在User中也有。會(huì)先在當(dāng)前對(duì)象里面找
User
Salary float64
Name string
}
func main() {
// 聲明結(jié)構(gòu)體
var u1 Employee
fmt.Printf("%T,%#v\n", u1, u1)
// 簡(jiǎn)短聲明并初始化結(jié)構(gòu)體
u2 := Employee{
User: User{
ID: 2,
Name: "u2",
Addr: Address{
Region: "北京市",
Street: "霍營(yíng)",
Number: "002",
},
},
Salary: 12,
}
fmt.Printf("%T,%#v\n", u2, u2)
// 屬性的訪問(wèn)和修改
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)
}
多個(gè)元素相同的嵌入所踊,必須指定全路徑訪問(wèn)
package main
import "fmt"
// 定義Address結(jié)構(gòu)體
type Address struct {
Region string
Street string
No string
}
// 定義User結(jié)構(gòu)體
type User struct {
ID int
Name string
Addr Address //命名結(jié)構(gòu)體嵌入
}
// 定義Company結(jié)構(gòu)體
type Company struct {
ID int
Name string
Addr Address
Salary float64
}
// 定義Employee結(jié)構(gòu)體
type Employee struct {
User //匿名結(jié)構(gòu)體嵌入
Company
Salary float64
Name string
}
func main() {
// 聲明結(jié)構(gòu)體
var u Employee
fmt.Printf("%T,%#v\n", u, u)
//匿名嵌入的結(jié)構(gòu)體屬性相同時(shí)泌枪,必須使用全路徑
u.Company.Name = "companyname"
u.User.Name = "wpfs"
fmt.Println(u.Company.Name)
fmt.Println(u.User.Name)
}
指針類型嵌入
結(jié)構(gòu)體嵌入(命名&匿名)類型也可以為結(jié)構(gòu)體指針
命名型
package main
import "fmt"
// 定義Address結(jié)構(gòu)體
type Address struct {
Region string
Street string
Number string
}
// 定義User結(jié)構(gòu)體
type User struct {
ID int
Name string
Addr *Address // 嵌入命名結(jié)構(gòu)體指針類型
}
func main() {
//聲明結(jié)構(gòu)體
var u1 User
fmt.Printf("%#v\n", u1)
u2 := User{
ID: 1,
Name: "wpfs",
Addr: &Address{"北京", "霍營(yíng)", "01"},
}
fmt.Printf("%#v\n", u2)
fmt.Printf("%#v\n", u2.Addr)
// 2種訪問(wèn)指針類型的元素和修改的方式
(*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結(jié)構(gòu)體
type Address struct {
Region string
Street string
Number string
}
// 定義User結(jié)構(gòu)體
type User struct {
ID int
Name string
Addr Address
}
// 定義Employee結(jié)構(gòu)體
type Employee struct {
*User // 匿名嵌入指針類型
Salary float64
Name string
}
func main() {
//聲明結(jié)構(gòu)體
var u Employee
fmt.Printf("%#v\n", u)
//簡(jiǎn)短聲明并初始化結(jié)構(gòu)體
u1 := Employee{
User: &User{
ID: 1,
Name: "wpfs",
Addr: Address{"北京", "霍營(yíng)", "01"},
},
Salary: 1024,
Name: "eeu",
}
fmt.Printf("%#v\n", u1)
//訪問(wèn)與修改元素
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)
}