结构体
结构体(struct) 是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员。学过 C 或 C++ 的人都知道结构体,但在 Go 中,没有像 C++ 中的 class
类的概念,只有 struct
结构体的概念,所以也没有继承。
创建一个结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import "fmt"
type Student struct { name string sno string age int }
func main() { stu1 := Student{ name: "jpc", sno: "123456", age: 21, }
stu2 := Student{"jzw", "123123", 22} fmt.Println(stu1) fmt.Println(stu2)
}
|
创建匿名结构体
- 当定义好的结构体没有被显式初始化时,结构体的字段将会默认赋为相应类型的零值。
- 点操作符
.
可以用于对结构体的字段的赋值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package main
import "fmt"
func main() { stu := struct { name string sno string age int }{ name: "jhy", sno: "222222", age: 23, } stu.sno = "123321" fmt.Println(stu) }
|
匿名字段
在创建结构体时,字段可以只有类型没有字段名,这种字段称为 匿名字段 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package main
import "fmt"
type Student struct { string int }
func main() { stu := Student{"jpc", 21} fmt.Println(stu) fmt.Println(stu.string) fmt.Println(stu.int) }
|
结构体嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main
import "fmt"
type Score struct { math int english int }
type Student struct { name string sno string score Score }
func main() {
stu := Student{ name: "jpc", sno: "123456", } stu.score = Score{98, 56}
fmt.Println(stu) }
|
提升字段
结构体中如果有匿名的结构体类型字段,则该匿名结构体里的字段就称为 提升字段(Promoted Fields) 。这是因为提升字段就像是属于外部结构体一样,可以用外部结构体直接访问。
对上面程序稍作修改:
1 2 3 4 5
| type Student struct { name string sno string Score }
|
这样访问字段就可以从stu.score.math
直接变成stu.math
结构体比较
结构体比较可以用==运算符可以用 DeeplyEqual()函数
给结构体定义方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package main
import "fmt"
type Student struct { name string sno string age int }
func (stu Student) Show() { fmt.Println(stu.name) fmt.Println(stu.sno) fmt.Println(stu.age) }
func (stu *Student) AddAge(n int) { stu.age += n }
func main() { stu := Student{"jpc", "123456", 21} stu.AddAge(3) stu.Show() }
|
结构体的 Tag 标签
Tag
Go语言结构体成员Tag来指定对应的JSON名字。
1 2 3 4 5
| type Person struct { Name string `json:"name"` Target string `json:"target"` Spend int `json:"spend,omitempty"` }
|
Tag
中 json
对应值的第一部分用于指定 JSON
对象的名字,比如将 Go 语言中的 TotalCount
成员对应到 JSON
中的 total_count
对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
import ( "encoding/json" "fmt" )
type People struct { Name string `json:"name"` Addr string `json:"addr"` Age int `json:"age"` }
func main() { p1 := People{ Name: "谢老板", Addr: "海底餐厅", Age: 35, } data1, err := json.Marshal(p1) if err != nil { panic(err) } fmt.Printf("%s\n", data1) }
|
Tag 获取
Tag 的格式上面已经说了,它是由反引号括起来的一系列用空格分隔的 key:"value"
键值对序列.
使用反射的方法获取 Tag 步骤如下:
- 获取字段
- 获取 Tag
- 获取键值对
其中获取字段有三种方式,而获取键值对有两种方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" "reflect" )
type People struct { Name string `json:"name"` Addr string `json:"addr"` Age int `json:"age"` }
func main() { p := reflect.TypeOf(People{}) name, _ := p.FieldByName("Name") tag := name.Tag fmt.Println("Name Tag:", tag) keyValue, _ := tag.Lookup("json") fmt.Println("key: json, value:", keyValue) }
|