Wallet(钱包)
结构体,我们可以利用它存放 Bitcoin(比特币)
。./wallet_test.go:7:12: undefined: Wallet
Wallet
是什么,所以让我们告诉它。wallet_test.go:15: got 0 want 10
balance(余额)
变量来存储状态balance
字段。wallet_test.go:15: got 0 want 10
func (w Wallet) Deposit(amount int)
时,w
是来自我们调用方法的副本。wallet
,它就会被存储在内存的某处。你可以用 &myval
找到那块内存的地址。prints
来试验一下balance
的地址是不同的。因此,当我们在代码中更改 balance
的值时,我们处理的是来自测试的副本。因此,balance
在测试中没有被改变。*Wallet
而不是 Wallet
,你可以将其解读为「指向 wallet
的指针」。int
,因为当用来计数时它是不错的类型!int
的表现来说已经很好了,但问题是它不具有描述性。type MyName OriginalType
Bitcoin(比特币)
,你只需要用 Bitcoin(999)
的语法就可以了。fmt
包中定义的。当使用 %s
打印格式化的字符串时,你可以定义此类型的打印方式。String()
方法。wallet_test.go:18: got 10 BTC want 20 BTC
Withdraw(提取)
函数。Deposit()
相反./wallet_test.go:26:9: wallet.Withdraw undefined (type Wallet has no field or method Withdraw)
wallet_test.go:33: got 20 BTC want 10 BTC
Withdraw
时标记出现的问题呢?err
,以便调用者检查并执行相应操作。Withdraw
返回一个错误,而余额应该保持不变。nil
。nil
是其他编程语言的 null
。错误可以是 nil
,因为返回类型是 error
,这是一个接口。如果你看到一个函数,它接受参数或返回值的类型是接口,它们就可以是 nil
。nil
的值,它将会引发 运行时的 panic。这很糟糕!你应该确保你检查了 nil
的值。./wallet_test.go:31:25: wallet.Withdraw(Bitcoin(100)) used as value
Withdraw
的意图只是调用它,它永远不会返回一个值。为了使它编译通过,我们需要更改它,以便它有一个返回类型。Withdraw
方法返回 error
,现在我们必须返回 一些东西,所以我们就返回 nil
好了。errors
导入到代码中。errors.New
创建了一个新的 error
,并带有你选择的消息。string
的助手方法来比较。t.Fatal
。如果它被调用,它将停止测试。这是因为我们不希望对返回的错误进行更多断言。如果没有这个,测试将继续进行下一步,并且因为一个空指针而引起 panic。wallet_test.go:61: got err 'oh no' want 'cannot withdraw, insufficient funds'
Withdraw
代码中都有重复的错误消息。var
关键字允许我们定义包的全局值。Withdraw
函数看起来很清晰。InsufficientFundsError
进行相等的检查,并采取相应的操作。errcheck
,这是许多可用的 linters(代码检测工具)之一。go get -u github.com/kisielk/errcheck
errcheck .
。wallet_test.go:17:18: wallet.Withdraw(Bitcoin(10))
withdraw
的场景相对应,因为我们没有检查 Withdraw
是否成功,因此没有返回错误。