首页 > 编程笔记 > Go语言笔记 阅读:12

Go语言结构体嵌套的用法(非常详细)

结构体由多个成员组成。由于每个成员可以设置为不同的数据类型,因此结构体成员的数据类型也可以设置为结构体,这就是结构体的嵌套功能。

Go语言程序中,结构体的嵌套是将一个结构体的成员设置为另一个结构体。代码如下:
type exam struct {
    subject string
    score int
}
type info struct {
    name string
    age int
    record exam
}
在上述代码中,定义两个结构体 exam 和 info,其中,结构体 info 中的成员 record 的数据类型指向结构体 exam,说明该成员为结构体类型。这样,info 结构体就拥有了 exam 的所有成员,实例化后可以自由访问 exam 的所有成员,这里使用的就是结构体的嵌套。

在实例化两个结构体时,record 成员的值是 exam 结构体的实例。代码如下:
package main

import (
    "fmt"
)

type exam struct {
    subject string
    score int
}
type info struct {
    name string
    age int
    record exam
}

func main(){
    //实例化结构体
    e := exam{subject: "机械制图", score: 80}
    i := info{name: "江南", age: 23, record: e}
    //访问结构体成员
    fmt.Print("姓名: %v\n", i.name)
    fmt.Print("年龄: %v\n", i.age)
    fmt.Print("考试科目: %v\n", i.record.subject)
    fmt.Print("考试分数: %v\n", i.record.score)
}
运行结果如下:

姓名: 江南
年龄: 23
考试科目: 机械制图
考试分数: 80

在上述代码中,分别实例化两个结构体。在实例化 info 结构体时,record 成员的值是创建的 exam 结构体的实例。通过结构体实例访问 exam 结构体的成员同样使用点(.)操作符。如 record.subject,i 是结构体 info 的实例名,record 是结构体 info 的成员,subject 是结构体 exam 的成员。

【实例】输出长春市简介。使用结构体的嵌套展示关于长春市的城市名称、电话区号和著名景点等信息。代码如下:
package main

import (
    "encoding/json"
    "fmt"
)

type spots struct {
    //定义结构体,成员为切片类型,切片元素同样为结构体
    Spot []struct{
        Name    string
        Level   string
        Ticket  int
    }
}
type city struct {
    name string
    code string
    tourism spots
}

func main(){
    var s spots //实例化spots结构体
    //实例化city结构体
    c := city{name: "长春市", code: "0431", tourism: s}
    //JSON 格式的数据
    j := `{"spot":
        [
            {"name":"净月潭公园","level":"AAAAA 级","ticket":30},
            {"name":"东北虎园","level":"AAAAA 级","ticket":60},
            {"name":"长影世纪城","level":"AAAAA 级","ticket":240}
        ]
    }`
    json.Unmarshal([]byte(j), &s) //JSON 转换为结构体
    fmt.Print("城市名称: %v\n", c.name)
    fmt.Print("电话区号: %v\n", c.code)
    fmt.Print("著名景点如下:\n")
    for _, v := range s.Spot {
        //访问结构体成员
        fmt.Print("景点名称: %v\t", v.Name)
        fmt.Print("景点级别: %v\t", v.Level)
        fmt.Print("门票价格: %v 元\n", v.Ticket)
    }
}
运行结果如下:

城市名称: 长春市
电话区号: 0431
著名景点如下:
景点名称: 净月潭公园 景点级别: AAAAA 级 门票价格: 30 元
景点名称: 东北虎园 景点级别: AAAAA 级 门票价格: 60 元
景点名称: 长影世纪城 景点级别: AAAAA 级 门票价格: 240 元


结构体是一种数据类型,所以它也可以作为匿名成员。这时,访问嵌套的结构体成员只需要使用“结构体实例名.成员名”即可。代码如下:
package main

import (
    "fmt"
)

type exam struct {
    subject string
    score int
}
type info struct {
    name string
    age int
    exam //匿名成员
}

func main(){
    //实例化结构体
    e := exam{subject: "机械制图", score: 80}
    i := info{name: "江南", age: 23, exam: e}
    //访问结构体成员
    fmt.Print("姓名: %v\n", i.name)
    fmt.Print("年龄: %v\n", i.age)
    fmt.Print("考试科目: %v\n", i.subject)
    fmt.Print("考试分数: %v\n", i.score)
}
在上述代码中,通过结构体实例 i 可以直接访问 exam 结构体的成员 subject 和 score,不必使用 i.exam.subject 和 i.exam.score。运行结果如下:

姓名: 江南
年龄: 23
考试科目: 机械制图
考试分数: 80


匿名结构体也可以应用在结构体的嵌套中。在嵌套结构体中使用匿名结构体的好处是可以简化定义多个结构体的步骤,使代码更简洁。代码如下:
package main

import (
    "fmt"
)

type exam struct {
    subject string
    score int
}

type info struct {
    name string
    age int
    record exam
    //结构体嵌套中使用匿名结构体
    job struct {
        position string
        year int
    }
}

func main(){
    //实例化结构体
    e := exam{subject: "计算机技术与软件专业技术资格", score: 80}
    i := info{name: "江南", age: 30, record: e}
    i.job.position = "项目经理"
    i.job.year = 5
    //访问结构体成员
    fmt.Print("姓名: %v\n", i.name)
    fmt.Print("年龄: %v\n", i.age)
    fmt.Print("职位: %v\n", i.job.position)
    fmt.Print("工作年限: %v 年\n", i.job.year)
    fmt.Print("考试科目: %v\n", i.record.subject)
    fmt.Print("考试分数: %v\n", i.record.score)
}
运行结果为:

姓名: 江南
年龄: 30
职位: 项目经理
工作年限: 5 年
考试科目: 计算机技术与软件专业技术资格
考试分数: 80

在上述代码中,在定义结构体 info 中的成员 job 时使用匿名结构体,在代码中可以更直观地显示嵌套结构体的数据结构

相关文章