[golang ] 结构体
[golang ] 结构体
结构体的定义:
type person struct {
name string
age int
}
使用:
var lily person
未赋值的结构体,其中所有字段拥有对应类型的零值。与 map 不同,声明后显式赋值为空或没有赋值,效果都一样,都是将结构体内各字段设置为零值,所以上面的声明和下面赋值的结果是等效的:
lily := person{}
初始化结构体中的字段有两种形式,一种是不指定字段名,按照结构体中字段声明的顺序依次指定初始值;另一种类似 map,指定键值对:
func main() {
foo := person{
"foo",
1,
}
bar := person{
name: "bar",
age: 2,
}
fmt.Println(foo, bar) // {foo 1} {bar 2}
}
结构体中字段的访问:
foo.age = 22
fmt.Println(foo.name)
注意与 map 区分,后者使用方括号访问字段。
匿名结构体
可以声明变量时实现结构体的功能而不单独声明该结构体类型,此时隐式地创建了匿名结构体,这在将其他数据转成 Go 中的结构体或将 Go 数据转成 JSON 时会常用到:
func main() {
var person struct {
name string
age int
}
person.name = "foo"
pet := struct {
name string
leg int
}{
name: "blah",
leg: 4,
}
fmt.Println(person, pet) // {foo 0} {blah 4}
}
结构体的比较和转换
结构体是否可进行比较取决于其中包含的字段是不是全部可比较,如果包含 slice,map 类型的字段,则不能被比较。
不同类型的原始值之间不能进行比较,同埋,不同类型的结构体也一样。
但有种情况下,结构体之间可进行互相转换:结构体内字段名一样,字段类型一致,且字段顺序也一样。转换后即可进行比较。
考察如下示例代码:
func main() {
type person1 struct {
name string
age int
}
// 可转换,因为字段名,类型,顺序均匹配
type person2 struct {
name string
age int
}
// 不可转换,因为字段顺序不一致
type person3 struct {
age int
name string
}
// 不可转换,因为字段名不匹配
type person4 struct {
firstName string
age int
}
// 不可转换,因为有多余字段
type person5 struct {
name string
age int
gender byte
}
}
另外,如果进行比较的两个结构体,至少一个是匿名结构体的话,且满足字段名,类型和顺序一致,则无须转换直接比较。