7.2 嵌套结构体、自定义默认值以及如何比较结构体

嵌套结构体

一个结构体中的字段可以是另一个结构体类型的变量,这就缔造了嵌套形式的结构体类型

  • type superhero struct {
            name string
            age int
            addr address
    }
  • type address struct {
            city string
            street string
            number int

访问内嵌结构体的字段,依然是使用"."语法

s := superhero{ ... }
fmt.Println(s.addr.city, s.addr.street, s.addr.number)

// 结构体中某个字段的数据类型可以又是结构体,由此构成多层级的结构体嵌套
package main
import "fmt"
type superhero struct {
    name string
    age  int 
    addr address
}
type address struct {
    city   string
    street string
    number int 
}

func main() {
    s := superhero{
        name: "Batman",
        age:  32,
        addr: address{
            city:   "Gotham",
            street: "Mountain Drive",
            number: 1007,
        },
    }
    fmt.Printf("%#v\n", s) // #v输出类型信息
	// main.superhero{name:"Batman", age:32, addr:main.address{city:"Got
	// ham", street:"Mountain Drive", number:1007}}
	 
    fmt.Println(s.name, s.age, s.addr.city,
        s.addr.street, s.addr.number)
	// Batman 32 Gotham Mountain Drive 1007
}

自定义默认值

在不为结构体变量中的各个字段显式指定初值的情况下,编译器会自动将其初始化为适当类型零值。

类型

零值

数值型

整型

0

浮点型

0.0

逻辑型

布尔型

false

容器型

字符串

""

切片

[]

映射

{}

引用型

指针

nil

函数

nil

接口

nil

通道

nil

Go语言没有提供为变量设置自定义默认值的内置方法,但可以通过定义构造函数来间接地达到类似的效果。构造函数负责创建包括结构体在内的特定类型的变量,并在没有显式提供构造参数的情况下将其设置为自定义的默认值。

  • type alarm struct { ... }
  • func newAlarm(time string) alarm {
            a := alarm{time: time, sound: "Klaxon" /* 自定义默认值 */}
            return a
    }
  • a := newAlarm("7:00")

通过构造函数设置自定义默认值,只是一种语法技巧,而非Go语言规范的一部分。

// Go语言没有提供自定义结构体字段默认值的内置方法,但可以通过构造函数为结构体
// 的全部或部分字段提供默认值
package main
import "fmt"
type alarm struct {
    time  string
    sound string
}
func newAlarm(time string) alarm {
    a := alarm{time: time, sound: "Klaxon" /* 自定义默认值 */}
    return a
}
func main() {
    a := newAlarm("7:00")
    fmt.Printf("%+v\n", a)	// {time:7:00 sound:Klaxon} 
}

比较结构体(3种方法)

结构体变量之间可以进行比较,但仅限于相等(==)和不等(!=)的判断,没有包含、大小于的比较。

只有当两个结构体变量对应字段的值都相等时它们才相等(顺序也在对应性的要求内),只要有一个字段不等,这两个结构体变量就不等。

只有同一种结构体类型的变量之间才能进行比较,否则将导致编译错误。(即使结构体的每一个字段的名称、字段值、顺序都相等,但结构体名字不同,也无法比较,其被视为不同的结构体)。

要检查结构体变量的类型,可选择以下三种方法中的任意一种:

  • fmt.Printf("%#v\n", a)
    • main.drink{name:"", ice:false}
  • fmt.Printf("%T\n", a)(首次出现)
    • main.drink
  • fmt.Println(reflect.TypeOf(a))
    • main.drink
// 比较结构体变量的类型
// 类型相同的结构变量,可以通过“==”和“!=”,做相等性和不等性的比较
package main
import "fmt"
type drink struct {
    name string
    ice  bool 
}
func main() {
    a := drink{name: "Lemonade", ice: true}
    b := drink{name: "Lemonade", ice: true}

    c := drink{name: "Orangeade", ice: true}

    d := drink{name: "Lemonade", ice: false}

    e := drink{name: "Orangeade", ice: false}

    fmt.Println(a == b, a != b)	// true false
    fmt.Println(a == c, a != c)	// false true
    fmt.Println(a == d, a != d)	// false true
    fmt.Println(a == e, a != e)	// false true
}
// 检查结构体变量的类型
// 借助反射查看结构体变量的类型
package main
import (
    "fmt"
    "reflect"
)
type drink struct {
    name string
    ice  bool 
}
func main() {
    a := drink{}

    fmt.Printf("%#v\n", a)	//main.drink{name:"", ice:false}
    fmt.Printf("%T\n", a)		// main.drink
    fmt.Println(reflect.TypeOf(a))	// main.drink
}

  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值