Bitcoin
を預金するWallet
構造体を作成しましょう。./wallet_test.go:7:12: undefined: Wallet
Wallet
が何であるかを知らないので、それを伝えましょう。wallet_test.go:15: got 0 want 10
var
、タイプtype
、関数func
)が小文字の記号で始まっている場合は、それは定義されているパッケージの外側のプライベートなものです。receiver
」変数を使用して、構造体の内部のbalance
フィールドにアクセスできることを覚えておいてください。wallet_test.go:15: got 0 want 10
balance
メソッドはその現在の状態を返す必要があります。func (w Wallet) Deposit(amount int)
を呼び出すとき、 w
はメソッドの呼び出し元のコピーです。&myVal
で確認できます。&
シンボルのアドレスを持つものへのポインタを取得します。balances
のアドレスが異なることがわかります。 したがって、コード内のbalances
の値を変更する場合、テストから得られたもののコピーに取り組んでいます。 したがって、テストのバランスは変更されません。Wallet
ではなく*Wallet
であり、Wallet
へのポインターとして読み取ることができることです。(*w)
を使用した上記のコードは完全に有効です。 ただし、Goの作成者はこの表記を扱いにくいと判断したため、この言語では、明示的な逆参照なしでw.balance
を記述できます。 構造体へのこれらのポインタには、独自の名前 struct pointers があり、自動的に逆参照されます。Balance
を変更する必要はありません。 ただし、慣例では、一貫性を保つために、メソッドレシーバーのタイプを同じに保つ必要があります。int
を使用しているのは、物事を数えるのに適したタイプだからです。struct
を作成するのは少しやり過ぎのようです。 int
は、動作の点では問題ありませんが、説明的ではありません。type MyName OriginalType
です。Bitcoin
を作成するには、Bitcoin(999)
という構文を使用します。fmt
パッケージで定義されており、%s
形式の文字列を prints で使用したときにタイプがどのように印刷されるかを定義できます。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
」しようとするとどうなりますか? 当面の要件は、当座貸越施設がないことを前提としています。Withdraw
を使用する場合、どのように問題を通知しますか?err
を返すことは慣用的です。Withdraw
がエラーを返すようにしたいのですが、あなたが持っている以上のものを取り出そうとしても、balance
は変わらないはずです。nil
の場合、テストに失敗してエラーが返されたことを確認します。nil
は他のプログラミング言語のnull
と同義です。 Withdraw
の戻り値の型はインターフェイスであるerror
になるため、エラーは nil
になる可能性があります。 引数を取る関数、またはインターフェイスである値を返す関数がある場合、それらは nillable(潰しが利かない) になる可能性があります。null
のようにnil
である値にアクセスしようとすると、ランタイムパニックがスローされます。 これは悪いです! nil
をチェックすることを確認する必要があります。./wallet_test.go:31:25: wallet.Withdraw(Bitcoin(100)) used as value
Withdraw
を使用する以前の意図は単にそれを呼び出すことであり、決して値を返しません。 このコンパイルを行うには、戻り値の型を持つように変更する必要があります。Withdraw
メソッドを修正してerror
を返すようにしました。 ここでは 何か を返す必要があるので、nil
を返します。errors
をコードにインポートすることを忘れないでください。errors.New
は、選択したメッセージで新しいerror
を作成します。string
のヘルパーを更新します。t.Fatal
を導入しました。 これは、周りにエラーがない場合に返されるエラーについてこれ以上アサーションを作成したくないためです。 これがなければ、テストは次のステップに進み、nilポインターのためにパニックになります。wallet_test.go:61: got err 'oh no' want 'cannot withdraw, insufficient funds'
Withdraw
コードの両方でエラーメッセージが重複しています。var
キーワードを使用すると、パッケージにグローバルな値を定義できます。Withdraw
関数が非常に明確になったので、これ自体は前向きな変更です。ErrInsufficientFunds
に対して等号チェックを行い、それに応じて行動できることがわかります。errcheck
をインストールします。go get -u github.com/kisielk/errcheck
errcheck .
を実行します。wallet_test.go:17:18: wallet.Withdraw(Bitcoin(10))
Withdraw
が成功した場合にエラーが返されないことを確認していないためです。nil
であるかどうかを確認する必要があります。そうでない場合、ランタイム例外が発生する可能性があります。コンパイラーはここでは役立ちません。