指针接收者
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 8 课,共 68 课。
值接收者处理结构体的副本,而指针接收者直接处理原始结构体实例。使用指针接收者定义方法时,该方法可以修改原始数据,因为它接收的是指向结构体的指针,而不是副本。
要创建指针接收者,请在接收者声明中的类型名前加上星号 *:
type Person struct {
Name string
Age int
}
func (p *Person) haveBirthday() {
p.Age++ // 这会修改原始结构体
}在这个示例中,(p *Person) 是一个指针接收者。当你在 Person 实例上调用 haveBirthday 方法时,该方法会接收指向原始结构体的指针。通过这个指针对结构体字段所做的任何更改,都会永久修改原始数据。
当方法需要更新结构体的字段时,指针接收者必不可少,因此非常适合用于改变数据状态的操作。
挑战
简单在这个挑战中,你将通过构建一个简单的银行账户系统,练习使用指针接收者创建方法。你将创建一个 Account 结构体,并定义可以使用指针接收者修改账户余额的方法。
你将收到 3 个输入:
- 表示账户持有人姓名的字符串(例如,
"John Smith") - 表示账户初始余额的字符串(例如,
"1000.50") - 表示交易金额的字符串(例如,
"250.75")
你的任务是:
- 定义一个包含两个字段的
Account结构体:Name(字符串)和Balance(float64) - 创建一个名为
deposit的方法,使用指针接收者将给定金额加到账户余额中 - 创建一个名为
withdraw的方法,使用指针接收者从账户余额中减去给定金额 - 创建一个名为
displayBalance的方法,使用值接收者按以下格式打印账户信息:"Account: [name], Balance: $[balance]" - 解析输入,创建一个
Account实例 - 调用
displayBalance显示初始余额 - 使用交易金额调用
deposit - 调用
displayBalance显示存款后的余额 - 使用交易金额调用
withdraw - 调用
displayBalance显示最终余额
余额应显示为精确到小数点后两位。这个挑战演示了指针接收者如何让方法修改原始结构体数据,而值接收者处理的是副本。
亲手试试
package main
import (
"fmt"
"strconv"
)
// TODO: 在这里定义 Account 结构体
// TODO: 在这里定义使用指针接收者的 deposit 方法
// TODO: 在这里定义使用指针接收者的 withdraw 方法
// TODO: 在这里定义使用值接收者的 displayBalance 方法
func main() {
// 读取输入
var name string
var initialBalanceStr string
var transactionAmountStr string
fmt.Scanln(&name)
fmt.Scanln(&initialBalanceStr)
fmt.Scanln(&transactionAmountStr)
// 将字符串输入转换为合适的数据类型
initialBalance, _ := strconv.ParseFloat(initialBalanceStr, 64)
transactionAmount, _ := strconv.ParseFloat(transactionAmountStr, 64)
// TODO: 创建一个 Account 实例
// TODO: 显示初始余额,执行存款,显示余额,执行取款,显示最终余额
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Go 在线编译器