diff --git a/learn_go_with_tests/pointers_errors/wallet.go b/learn_go_with_tests/pointers_errors/wallet.go index cde9e66..0e7ddf2 100644 --- a/learn_go_with_tests/pointers_errors/wallet.go +++ b/learn_go_with_tests/pointers_errors/wallet.go @@ -1,12 +1,46 @@ package pointers_errors +import "fmt" + +type Stringer interface { + String() string +} + +// creating a new type from an existing on +// The idea being it could be more descriptive +// but also you can declare methods on them +// which can be used to add domain specific functionality +type Bitcoin int + +// this let's us use fmt strings with %s on the Bitcoin type +func (b Bitcoin) String() string { + return fmt.Sprintf("%d BTC", b) +} + type Wallet struct { - balance int + balance Bitcoin } -func (w Wallet) Deposit(amount int) { +func (w *Wallet) Deposit(amount Bitcoin) { + // Need a pointer because the func args are copied + // so w Wallet is a copy of wallet. Not the actually refernce to the + // wallet that Deposit was called on. + + // Notice we don't have to derefence the pointer like in Balance because + // in go https://go.dev/ref/spec#Method_values struct pointers are automatically + // derefenced + w.balance += amount +} + +// Technically you do not need to change Balance to use a pointer receiver as taking a copy of the balance is fine. However, by convention you should keep your method receiver types the same for consistency. + +func (w *Wallet) Balance() Bitcoin { + // dereferences the pointer + // which as stated above didn't need to happen because go automatically + // dereferences struct pointers. + return (*w).balance } -func (w Wallet) Balance() int { - return 0 +func (w *Wallet) Withdraw(amount Bitcoin) { + w.balance -= amount } diff --git a/learn_go_with_tests/pointers_errors/wallet_test.go b/learn_go_with_tests/pointers_errors/wallet_test.go index 32de526..230d4bc 100644 --- a/learn_go_with_tests/pointers_errors/wallet_test.go +++ b/learn_go_with_tests/pointers_errors/wallet_test.go @@ -1,17 +1,40 @@ package pointers_errors -import "testing" +import ( + "fmt" + "testing" +) func TestWallet(t *testing.T) { - wallet := Wallet{} + t.Run("deposit", func(t *testing.T) { + wallet := Wallet{} - wallet.Deposit(10) + wallet.Deposit(10) - got := wallet.Balance() - want := 10 + got := wallet.Balance() - if got != want { - t.Errorf("got %d want %d", got, want) - } + // %p is placeholder for address in memory + fmt.Printf("address of balance in test is %p \n", &wallet.balance) + want := Bitcoin(10) + + if got != want { + // t.Errorf("got %d want %d", got, want) + t.Errorf("got %s want %s", got, want) + } + }) + + t.Run("withdraw", func(t *testing.T) { + wallet := Wallet{balance: Bitcoin(20)} + + wallet.Withdraw(Bitcoin(10)) + + got := wallet.Balance() + want := Bitcoin(10) + + if got != want { + t.Errorf("got %s want %s", got, want) + } + + }) }