美文网首页
指针和错误

指针和错误

作者: 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)
    })

}



相关文章

  • 指针和错误

    在 Go 中,如果一个符号(例如变量、类型、函数等)是以小写符号开头,那么它在 定义它的包之外 就是私有的。在 G...

  • go - 学习笔记

    基础 函数 指针 结构体 接口 错误 协程 通道 基础 函数 指针 结构体 接口 错误 协程 通道

  • C语言学习(第一天)

    C语言基本数据类型 输入和输出函数 指针入门 C语言指针实现数据交换 指针的常见错误 不可以使用已经被回收的变量 ...

  • C++ this指针

    this指针只能在类内部使用 this指针的好处—— 避免传参和内部成员变量有重名的时候导致的错误可以实现链式表达...

  • 说说最近的项目总结吧

    part1. 如何减少代码中的指针错误,我们知道空指针错误会试整个页面挂掉,所以这个错误要尽量避免 最近读到了一篇...

  • 经验总结(四):java常用类库

    Java常用类库 一:异常和错误分类 运行时异常: NullPointerException - 空指针引用异常 ...

  • Go-Pointer

    go 指针 声明指针类型 x 错误写法此时创建的是一个空指针,而空指针无法获取到内存地址,也就无法根据内存地址找到...

  • 42_内存操作经典问题分析二

    1. 常见内存错误 (1) 结构体成员指针未初始化——野指针(2)结构体成员指针未分配足够的内存——越界(3)内存...

  • malloc产生段错误可能是如下原因:

    malloc产生段错误可能是如下原因: 1、指针非法,比如使用没有初始化的指针(没有为此指针指向的对象分配空间),...

  • iOS 常见面试题总结

    1. 空指针、野指针以及僵尸对象的理解,如何避免野指针错误。解答:内存被释放的对象为僵尸对象(不能再使用的对象)。...

网友评论

      本文标题:指针和错误

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