编辑
2022-09-27
Golang
00
请注意,本文编写于 786 天前,最后修改于 785 天前,其中某些信息可能已经过时。

目录

结构体
定义结构体
声明结构体
初始化结构体
声明匿名结构体
访问字段
导出字段
嵌套结构体
组合结构体
结构体标签
结构体的存储特性

结构体

struct 是用户定义的类型,其中包含命名字段的集合。 可以将他看做支持组合,但不支持集成的 class

定义结构体

go
// type 表示引入一个新类型,struct 表示定义的是一个 结构体 // 定义一个 Person type Person struct { // 定义一些字段 Hobby string // 同类型可以合并定义 FirstName LastName string Age int }

声明结构体

我们可以像其他数据类型一样声明它

go
type Person struct { // 定义一些字段 Hobby string // 同类型可以合并定义 FirstName, LastName string Age int } func main() { var p1 Person fmt.Println("Person 1:", p1) }

image.png

正如我们所看到的,所有结构字段都用它们的零值初始化。 所以FirstNameandLastName被设置为空字符串,并且Age被设置为 0。

初始化结构体

go
func main() { var p1 = Person{ Hobby: "Piano", FirstName: "AA", LastName: "BB", Age: 22, } fmt.Println("Person 1:", p1) }

image.png

相关信息

结构体也支持没有字段名的初始化

  • 如果不填写字段名,就必须全不填写
  • 不填写字段名,就必须提供所有的值
go
func main() { var p1 = Person{ "Piano", "AA", "BB", 22, } fmt.Println("Person 1:", p1) }

声明匿名结构体

go
func main() { var a = struct { Name string }{"Golang"} fmt.Println("Anonymous:", a) }

image.png

访问字段

go
func main() { var p1 = Person{ "Piano", "AA", "BB", 22, } // 访问 p1 的 age fmt.Println(p1.age) }

我们也可以使用内置new函数

go
func main() { p := new(Person) p.FirstName = "AA" p.LastName = "BB" p.Age = 22 // new 的结果是一个指针的值 // &{ AA BB 22} fmt.Println(p) // AA fmt.Println(p.FirstName) }

注意

两个结构的所有对应字段也相等,则它们是相等的

go
func main() { var p1 = Person{"a", "b", 20} var p2 = Person{"a", "b", 20} // true fmt.Println(p1 == p2) }

导出字段

变量和函数的规则相同 如果使用小写标识符声明结构字段,它将不会被导出,并且仅对定义它的包可见

go
// 会被到处 type Person struct { FirstName, LastName string Age int // 不会被导出 hobby string } // 不会被导出 type person struct { FirstName, LastName string Age int zipCode string }

嵌套结构体

go
type Person struct { FirstName, LastName string Age int } // 新结构体将具有原始结构的所有属性 type SuperHero struct { // 在 Person 的基础拓展 Person Alias string } func main() { s := SuperHero{} s.FirstName = "AA" s.LastName = "BB" s.Age = 22 s.Alias = "CC" // {{AA BB 22} CC} fmt.Println(s) }

** 然而,这通常不被推荐,并且在大多数情况下,优先使用组合组合**

组合结构体

go
type Person struct { FirstName, LastName string Age int } type SuperHero struct { // 定义了一个值,类型是 Person Person Person Alias string } func main() { p := Person{"Bruce", "Wayne", 40} s := SuperHero{p, "batman"} fmt.Println(s) // 效果相同,但是更容易管理和控制 // {{AA BB 22} CC} fmt.Println(s) }

结构体标签

警告

????????????这里还没有太理解

结构体标签是对结构体字段的额外信息标签。

相关信息

JSON、BSON 等格式进行序列化及对象关系映射(Object Relational Mapping,简称 ORM)系统都会用到结构体标签,这些系统使用标签设定字段在处理时应该具备的特殊属性和可能发生的行为。这些信息都是静态的,无须实例化结构体,可以通过反射(reflect)获取到。

go
// Tag 在结构体字段后方书写的格式如下: `key1:"value1" key2:"value2"`

结构体标签由一个或多个键值对组成。 键与值使用冒号分隔,值用双引号括起来。键值对之间使用一个空格分隔。

go
type cat struct { Name string Type int `json:"type" id:"100"` } type Animal struct { Name string `json:"name"` Age int `json:"age"` }

结构体的存储特性

结构体是一种值的类型

当我们将 struct 传递给另变量时,该函数会生成 自己独立的 struct存储

go
package main import "fmt" type Point struct { X, Y float64 } func main() { p1 := Point{1, 2} p2 := p1 // Copy of p1 is assigned to p2 p2.X = 2 fmt.Println(p1) // Output: {1 2} fmt.Println(p2) // Output: {2 2} }

空结构体占用零字节的存储空间

go
package main import ( "fmt" "unsafe" ) func main() { var s struct{} fmt.Println(unsafe.Sizeof(s)) // Output: 0 }

本文作者:Silon汐冷

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!