美文网首页
指针和错误

指针和错误

作者: bocsoft | 来源:发表于2018-11-29 15:57 被阅读0次

    在 Go 中,如果一个符号(例如变量、类型、函数等)是以小写符号开头,那么它在 定义它的包之外 就是私有的。
    在 Go 中,当调用一个函数或方法时,参数会被复制。
    当调用 func (w Wallet) Deposit(amount int) 时,w 是来自我们调用方法的副本。
    Go 允许从现有的类型创建新的类型。

    类型别名有一个有趣的特性,你还可以对它们声明方法。当你希望在现有类型之上添加一些领域内特定的功能时,这将非常有用。

    在类型别名上创建方法的语法与结构上的语法相同。
    如果你看到一个函数,它接受参数或返回值的类型是接口,它们就可以是 nil。

    指针

    • 当你传值给函数或方法时,Go 会复制这些值。因此,如果你写的函数需要更改状态,你就需要用指针指向你想要更改的值

    • Go 取值的副本在大多数时候是有效的,但是有时候你不希望你的系统只使用副本,在这种情况下你需要传递一个引用。例如,非常庞大的数据或者你只想有一个实例(比如数据库连接池)

    • 指针可以是 nil

    • 当函数返回一个的指针,你需要确保检查过它是否为 nil,否则你可能会抛出一个执行异常,编译器在这里不能帮到你

    • nil 非常适合描述一个可能丢失的值

    错误

    • 错误是在调用函数或方法时表示失败的

    • 通过测试我们得出结论,在错误中检查字符串会导致测试不稳定。因此,我们用一个有意义的值重构了,这样就更容易测试代码,同时对于我们 API 的用户来说也更简单。

    • 错误处理的故事远远还没有结束,你可以做更复杂的事情,这里只是抛砖引玉。后面的部分将介绍更多的策略。

    • ​不要只是检查错误,要优雅地处理它们。

    package main
    
    import (
        "errors"
        "fmt"
    )
    
    //Bitcoin represents a number of Bitcoins
    type Bitcoin int
    
    func (b Bitcoin) String() string {
        return fmt.Sprintf("%d BTC", b)
    }
    
    //Wallet stores the number of Bitcoin someone owns
    type Wallet struct {
        balance Bitcoin
    }
    
    //Deposit will add some Bitcoin to a wallet
    func (w *Wallet) Deposit(amount Bitcoin) {
        w.balance += amount
    }
    
    //ErrInsufficientFunds means a wallet does not have enough Bitcoin to perform a withdraw
    var ErrInsufficientFunds = errors.New("cannot withdraw ,insufficient funds")
    
    //Withdraw subtracts some Bitcoin from the wallet
    func (w *Wallet) Withdraw(amount Bitcoin) error {
        if amount > w.balance {
            return ErrInsufficientFunds
        }
    
        w.balance -= amount
        return nil
    }
    
    //Balance returns the number of Bitcoin a wallet has
    func (w *Wallet) Balance() Bitcoin {
        return w.balance
    }
    
    
    package main
    
    import "testing"
    
    func assertBalance(t *testing.T, wallet Wallet, want Bitcoin) {
        t.Helper()
        got := wallet.Balance()
    
        if got != want {
            t.Errorf("got '%s' want '%s'", got, want)
        }
    }
    
    func assertNotError(t *testing.T, got error) {
        t.Helper()
        if got != nil {
            t.Fatal("got an error but didnot want one")
        }
    }
    
    func assertError(t *testing.T, got error, want error) {
        t.Helper()
        if got == nil {
            t.Fatal("didn't get an error but wanted one")
        }
    
        if got != want {
            t.Errorf("got '%s', want '%s'", got, want)
        }
    }
    
    func TestWallet(t *testing.T) {
    
        t.Run("Deposit", func(t *testing.T) {
            wallet := Wallet{}
            wallet.Deposit(Bitcoin(10))
            assertBalance(t, wallet, Bitcoin(10))
        })
    
        t.Run("Withdraw with funds", func(t *testing.T) {
            wallet := Wallet{balance: Bitcoin(20)}
            err := wallet.Withdraw(10)
    
            assertBalance(t, wallet, Bitcoin(10))
            assertNotError(t, err)
        })
    
        t.Run("Withdraw insufficient funds", func(t *testing.T) {
            startingBalance := Bitcoin(20)
            wallet := Wallet{startingBalance}
            err := wallet.Withdraw(Bitcoin(100))
    
            assertBalance(t, wallet, startingBalance)
            assertError(t, err, ErrInsufficientFunds)
        })
    
    }
    
    
    
    

    相关文章

      网友评论

          本文标题:指针和错误

          本文链接:https://www.haomeiwen.com/subject/dpsfcqtx.html