指向结构体的指针
本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 20 课,共 107 课。
处理结构体时,你通常会使用指针来避免复制大型数据结构,并修改原始结构体。指向结构体的指针保存着该结构体实例的内存地址。
你可以对现有结构体使用 & 运算符来创建结构体指针,也可以直接对结构体字面量使用取地址运算符。
type Person struct {
Name string
Age int
}
p := Person{Name: "Alice", Age: 30}
ptr := &p // 指向已有结构体的指针
// 或者直接创建
ptr2 := &Person{Name: "Bob", Age: 25}通过指针访问结构体字段时,Go 提供了一种方便的简写方式。不必写 (*ptr).Name,你只需写 ptr.Name。Go 会自动为你解引用指针。
ptr := &Person{Name: "Alice", Age: 30}
// 两种写法效果相同
fmt.Println((*ptr).Name) // 显式解引用
fmt.Println(ptr.Name) // 自动解引用修改字段时也会自动解引用。通过指针所做的更改会影响原始结构体。
p := Person{Name: "Alice", Age: 30}
ptr := &p
ptr.Age = 31 // 修改原始对象
fmt.Println(p.Age) // 31结构体指针是 Go 面向对象编程模式的重要组成部分。它们可以让方法修改接收者状态,让大型结构体高效地传递给函数,并为构建树和链表等链式数据结构奠定基础。
挑战
简单让我们构建一个银行账户系统,演示结构体指针如何高效地修改原始数据。你将创建一个账户,并通过指针操作更新账户信息。
你将把代码分成两个文件:
account.go:定义一个BankAccount结构体,包含Owner(string)、Balance(float64)和AccountNumber(string)字段。创建一个名为NewAccount的函数,它接收账户所有者姓名和账户号码作为参数,并返回一个指向新建BankAccount的指针,初始余额为 0。再创建一个Deposit函数,它接收一个*BankAccount指针和一笔金额,然后通过指针将这笔金额加到账户余额中。main.go:从输入中读取账户信息,使用构造函数(该函数会返回一个指针)创建账户,通过指针存入一笔金额,并显示账户详情,以确认余额已修改。
将提供以下输入:
- 第 1 行:账户所有者姓名
- 第 2 行:账户号码
- 第 3 行:存款金额(浮点数)
输出格式:
Account: [AccountNumber]
Owner: [Owner]
Balance: [Balance]例如,给定 John Smith、ACC-12345 和 500.50,你的输出应为:
Account: ACC-12345
Owner: John Smith
Balance: 500.50请记住,NewAccount 函数应使用 & 运算符返回 *BankAccount,而 Deposit 函数可以使用 Go 的自动解引用功能,通过指针直接修改余额(例如,使用 account.Balance,而不是 (*account).Balance)。
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 读取账户所有者姓名
ownerName, _ := reader.ReadString('\n')
ownerName = strings.TrimSpace(ownerName)
// 读取账号
accountNumber, _ := reader.ReadString('\n')
accountNumber = strings.TrimSpace(accountNumber)
// 读取存款金额
amountStr, _ := reader.ReadString('\n')
amountStr = strings.TrimSpace(amountStr)
amount, _ := strconv.ParseFloat(amountStr, 64)
// TODO:使用 NewAccount 函数创建新账户(返回一个指针)
// TODO:使用账户指针调用 Deposit 函数进行存款
// TODO:按要求的格式输出账户详情:
// 账户:[AccountNumber]
// 所有者:[Owner]
// 余额:[Balance]
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Go 在线编译器