go struct
go不是面向对象语言,没有类的概念,它通过struct(structure简称)为开发者提供了自定义类型的方法。像面向对象中的类一样,struct可以用来管理一组属性集合,只是没有继承功能。
声明一个struct
type Person struct {
name string
email string
age int
}
通过type关键字定义了一个名为Person的struct, 该struct包含name,email和age属性以及它们的类型。
如果属性中类型相同也可以写在同一行。
type Person struct {
name, email string
age int
}
struct的getter和setter方法:
# 带有属性名(字段名顺序无关)
p := Person {
name: "Timy",
email: "timy@gmail.com",
age: 20,
}
# 也可以这样写:
var p Person
p.name = "Timy"
p.email = "timy@gmail.com"
p.age = 20
# 或者更简单的:
p := Person{"Timy","timy@gmail.com", 20}
# 访问struct的属性
fmt.Println(p.name) //返回Timy
注: 上面带有属性名赋值的代码中,最后一行必须有逗号,这样go在编译时就不会自动在最后一行加上分号而导致错误。
你也可以只声明一部分属性,其它属性留空(会默认为对应类型的空值)
p := Person {
name: "Romy",
}
fmt.Println(p)
# 会打印出{Romy 0}即: Romy, "", 0. 后两个分别为string和int的默认值。
有一点注意的是p := Person{"Timy"}这种写法是不可以的,它会严格验证字段数量。
嵌套类型struct:
type Roles struct {
roleName string
}
type Person struct {
name, email string
age int
roles Roles
}
roles := Roles{"admin"}
p := Person{
name: "Jimy",
email: "Jimy@gmail.com",
age: 30,
roles: roles,
}
fmt.Println(p.roles.roleName) #=> admin
匿名struct
不用提前声明struct名称,直接创建struct,在创建一个不需要复用的struct时比较有用。
jimy := struct {
name, email string
age int
} {
name: "Jimy",
email: "Jimy@gmail.com",
age: 30,
}
fmt.Println(jimy.name)
struct的指针
除了直接创建struct,我们还可以创建指向一个struct的指针。
p := &Person{
name: "Jimy",
email: "Jimy@gmail.com",
age: 30,
}
fmt.Println(p.name) //这时候p是一个指针
匿名字段
在声明struct时,你可以不指定字段名,只指定类型,这样go会自动将类型映射为字段名。
type User struct {
string
int
}
u := User{"Mr blue", 100}
fmt.Println(u.string) #=> Mr blue
Promoted fields
我们上面已经看到在只声明值类型时,go会自动的将其映射成字段名,在嵌套struct中也有类似的机制.
type Roles struct {
roleName string
}
type Person struct {
name, email string
age int
Roles
}
p := Person{
name: "Jimy",
email: "Jimy@gmail.com",
age: 30,
Roles: Roles{"admin"},
}
fmt.Println(p.Roles.roleName) #=> admin
struct比较
两个struct可以进行比较,如果它们属于同一个类型,且有相同的值
p := Person {
name: "Romy", age: 0,
}
p1 := Person {
name: "Romy", age: 0,
}
fmt.Println(p == p1)
p := Person {
name: "Romy", age: 30,
}
p1 := Person {
age: 30, name: "Romy",
}
fmt.Println(p == p1)
上面两种写法都会打印出true, 也表明struct比较是字段顺序无关的。
Struct field meta-data
struct也提供了向字段添加meta-data的能力。通常是用来给字段标注一下转换信息。但是你可以使用它存储任何meta-info最为标签或者说明
type Person struct {
name string `json:"name"`
email string `json:"email"`
age int `json:"age"`
}
上述代码中,我们声明了Person struct的字段为json类型,需要通过JSON encoding/decoding来操作。
参考: https://medium.com/rungo/structures-in-go-76377cc106a2
https://golangbyexample.com/struct-field-meta-or-tags/