GO语言学习(12) 初识结构体

目录

前言

1.结构体的声明

2.结构体的初始化 

 3.访问与修改字段

 4.结构体作为函数参数

5.结构体的比较 

 6.匿名字段

 7.结构体的嵌入

 8.结构体标签(Tags)


前言

        Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型,结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

1.结构体的声明

        以我们 “人” 为例子,我们每个人都有自己的名字和年龄。我们可以将“人”抽象为一类数据类型,其包括 名字 和 年龄 连个属性。在GO语言中,使用 type 和 struct 关键字定义结构体,我们可以将 “人” 这个数据类型使用 结构体 定义如下:

type Person struct {
    Name string    // 名字
    Age  int       // 年龄
}
  • 字段命名:每个字段名(属性,即上述代码中的Name,Age)需唯一,同一个结构体中不能有重复的字段名,但每个字段名对应的数据类型可以是任意类型。

2.结构体的初始化 

        接下来的章节都以上述定义的Person结构体为例子,主要有以下3中初始化的方法:

  • 字面量初始化
// 按顺序赋值(需全部字段)
p1 := Person{"Alice", 30}

// 指定字段名赋值(可省略部分字段,未指定字段为零值)
p2 := Person{Name: "Bob", Age: 25}
  •  使用 new 函数:返回指针,字段初始化为零值。
p3 := new(Person)  // p3 是 *Person 类型
p3.Name = "Charlie"
  •  Var声明:初始化为零值结构体。
var p4 Person
p4.Name = "Dave"

 3.访问与修改字段

        通过点号 . 操作符访问或修改字段:

fmt.Println(p1.Name)  // 输出 p1的Name属性的值,即"Alice"
p2.Age = 26           // 修改p2的 Age 字段

 4.结构体作为函数参数

  • 值接收者:操作结构体的副本,不影响原对象。
func (p Person) SayHello() {
    fmt.Printf("Hello, I'm %s\n", p.Name)
}
  • 指针接收者:操作实际对象,可修改字段。 
func (p *Person) SetAge(newAge int) {
    p.Age = newAge
}

5.结构体的比较 

  • 可比较性:若所有字段均为可比较类型(如基本类型、数组、指针等),则结构体可比较。
p1 := Person{"Alice", 30}
p2 := Person{"Alice", 30}
fmt.Println(p1 == p2) // true
  •  不可比较情况:若包含不可比较字段(如切片、映射),编译时报错。
type Data struct {
    Info map[string]int // 包含 map,结构体不可比较
}

 6.匿名字段

  • 匿名字段没有显式名称,仅指定类型:
type Data struct {
    int
    string
}
  • 访问时直接使用类型名: 
d := Data{42, "answer"}
fmt.Println(d.int) // 42

 7.结构体的嵌入

  • Go通过嵌入其他结构体实现组合,而非继承。我们以公司当中的员工为例,员工也是人(Person),所以人(Person)的属性一定都是员工的属性,此外员工还有“职称”的属性,定义如下:

type Employee struct {
    Person     // 嵌入 Person 结构体(匿名字段)
    JobTitle string
}
  •  嵌入字段的字段可直接访问:
e := Employee{Person{"Eve", 30}, "Engineer"}
fmt.Println(e.Name)  // 直接访问嵌入的 Person.Name

 8.结构体标签(Tags)

  • 标签是附加到字段的元数据,可通过反射读取,常用于序列化。
type User struct {
    Name string `json:"name" xml:"name"`
    Age  int    `json:"age"`
}
  • 使用 reflect 包解析标签: 
t := reflect.TypeOf(User{})
field := t.Field(0)
fmt.Println(field.Tag.Get("json")) // 输出 "name"

        关于结构体标签和反射机制的内容,详情看见GO语言学习(15)结构体标签与反射机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值