Skip to content

【1】结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。

go
package main
import (
        "fmt"
)

//定义动物结构体:
type Animal struct{
        Age int
        weight float32
}

//给Animal绑定方法:喊叫:
func (an *Animal) Shout(){
        fmt.Println("我可以大声喊叫")
}

////给Animal绑定方法:自我展示:
func (an *Animal) showInfo(){
        fmt.Printf("动物的年龄是:%v,动物的体重是:%v",an.Age,an.weight)
}

//定义结构体:Cat
type Cat struct{
        //为了复用性,体现继承思维,嵌入匿名结构体:——》将Animal中的字段和方法都达到复用
        Animal
}

//对Cat绑定特有的方法:
func (c *Cat) scratch(){
        fmt.Println("我是小猫,我可以挠人")
}

func main(){
        //创建Cat结构体示例:
        cat := &Cat{}
        cat.Animal.Age = 3
        cat.Animal.weight = 10.6
        cat.Animal.Shout()
        cat.Animal.showInfo()
        cat.scratch()
}

【2】匿名结构体字段访问可以简化。

等价于:

cat.Age --->cat对应的结构体中找是否有Age字段,如果有直接使用,如果没有就去找嵌入的结构体类型中的Age 【3】当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分。

go
package main
import (
        "fmt"
)

//定义动物结构体:
type Animal struct{
        Age int
        weight float32
}

//给Animal绑定方法:喊叫:
func (an *Animal) Shout(){
        fmt.Println("我可以大声喊叫")
}

////给Animal绑定方法:自我展示:
func (an *Animal) showInfo(){
        fmt.Printf("动物的年龄是:%v,动物的体重是:%v",an.Age,an.weight)
}

//定义结构体:Cat
type Cat struct{
        //为了复用性,体现继承思维,嵌入匿名结构体:——》将Animal中的字段和方法都达到复用
        Animal
        Age int
}

func (c *Cat) showInfo(){
        fmt.Printf("~~~~~~~~动物的年龄是:%v,动物的体重是:%v",c.Age,c.weight)
}

//对Cat绑定特有的方法:
func (c *Cat) scratch(){
        fmt.Println("我是小猫,我可以挠人")
}

func main(){
        //创建Cat结构体示例:
        // cat := &Cat{}
        // cat.Age = 3
        // cat.weight = 10.6
        // cat.Shout()
        // cat.showInfo()
        // cat.scratch()

        cat := &Cat{}
        cat.weight = 9.4
        cat.Age = 10 //就近原则
        cat.Animal.Age = 20
        cat.showInfo()//就近原则
        cat.Animal.showInfo()
}

【4】Golang中支持多继承:如一个结构体嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。为了保证代码的简洁性,建议大家尽量不使用多重继承,很多语言就将多重继承去除了,但是Go中保留了。

go
package main
import (
        "fmt"
)

type A struct{
        a int
        b string
}

type B struct{
        c int
        d string
}

type C struct{
        A
        B
}

func main(){
        //构建C结构体实例:
        c := C{A{10,"aaa"},B{20,"ccc"}}
        fmt.Println(c)
}

【5】如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。

go
package main
import (
        "fmt"
)

type A struct{
        a int
        b string
}

type B struct{
        c int
        d string
        a int
}

type C struct{
        A
        B
}

func main(){
        //构建C结构体实例:
        c := C{A{10,"aaa"},B{20,"ccc",50}}
        fmt.Println(c.b)
        fmt.Println(c.d)
        fmt.Println(c.A.a)
        fmt.Println(c.B.a)
}

【6】结构体的匿名字段可以是基本数据类型。

【7】嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值。

【8】嵌入匿名结构体的指针也是可以的。

【9】结构体的字段可以是结构体类型的。(组合模式)

Java · Golang · Rust