🐸 青蛙编程网
首页 / Go / Go 基础 / 5. 结构体与方法

5. 结构体与方法

这是什么:结构体(struct) = 把一组相关数据捆在一起的类型;方法 = 带着接收者的函数,让这捆数据「会做事」。

为什么用:上一章的变量都是各自独立的散装数据,想表示「一个用户」就得写四个变量传来传去。Go 没有 class,用 struct + 方法组合照样能造出带数据和行为的对象。

如何用:先定义一个 User 结构体并初始化它,再给字段挂上方法,最后用嵌入结构体验「组合代替继承」。

5.1 定义与使用 struct

type User struct {
    Name string   // 首字母大写 = 公开字段
    Age  int
    tags  []string
}

func main() {
    u := User{Name: "青蛙", Age: 11}   // 字段名初始化(推荐)
    u.Age++                            // 点号访问
    fmt.Println(u.Age)                 // 12

    p := &User{Name: "熊猫"}           // 指针变量,但点号照用
    p.Age = 9                          // Go 自动帮你解引用
}

5.2 方法:自带接收者的函数

type User struct {
    Name string
    Age  int
}

// 值接收者:得到副本(不改原数据)
func (u User) IsAdult() bool {
    return u.Age >= 18
}

// 指针接收者:操作原数据(能改!)
func (u *User) Birthday() {
    u.Age++
}
u := User{Name: "青蛙", Age: 11}
u.Birthday()
fmt.Println(u.IsAdult(), u.Age)   // false 12

选择口诀:要改原数据/结构体大 → *T 指针接收者;只读小数据 → T。日常多半 *T。

5.3 组合代替继承(Go 无 class 的理由)

type Animal struct{ Name string }
func (a Animal) Eat() { fmt.Println(a.Name, "在吃") }

type Dog struct {
    Animal       // 嵌入(组合)
    Breed string
}

d := Dog{Animal: Animal{Name: "旺财"}, Breed: "柴犬"}
d.Eat()          // 直接调用嵌入结构的方法 → 旺财 在吃

「有得吃就吃」(组合优于继承)正是 Go 的设计取向,比 Java 多重抽象轻多了。

5.4 结构体标签(JSON 场景速递)

type Article struct {
    Title   string `json:"title"`
    Views   int    `json:"views"`
    IsHot   bool   `json:"is_hot,omitempty"` // 空值不输出
}

配合标准库 encoding/json 与后端教程(Web 返回 JSON)直接可用。

5.5 动手改

  1. 给 User 加方法 Describe() 返回「青蛙今年 12 岁」格式字符串
  2. 用指针接收者写 Rename(newName),验证原值变
  3. 给 Dog 嵌入 User —— 体感组合的自由

5.6 小结

  • struct 定义型,字段名: 初始化、点号访问
  • 方法 = 接收者 + 函数;改原数据用指针接收者
  • 嵌入= 组合,替代继承链的负担

下一章:接口与错误处理 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。