兄弟连Go语言培训分享闭包和错误处理

兄弟连区块链培训 · · 894 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

  “区块链+时代无疑会是下一个风口,然而现在的区块链行业专业型人才正在遭遇瓶颈”兄弟连教育区块链学院院长尹成表示,“希望能通过兄弟连教育区块链培训学院为社会为企业培养并输送更多优质的区块链高精尖型技术人才。

Go语言中的闭包同样也会引用到函数外的变量。闭包的实现确保只要闭包还被使用,那么

被闭包引用的变量会一直存在,例如:package main

import "fmt"


func main(){

    var j int = 5

a := func()(func()) { //圆括号中的func()表示返回值是一个func()函数

        var i int = 10

return func() { //这里返回一个匿名函数

            fmt.Printf("i, j: %v, %v\n", i, j)

        }

}() //花括号后带参数列表表示调用匿名函数,执行到这里变量a就等于了一个函数了.


a() //调用函数a


j *= 2 //修改函数外部的变量j


a() //再次调用函数a

}


运行结果:

i, j: 10, 5

i, j: 10, 10


在上面的例子中,变量 a 指向的闭包函数引用了局部变量 i 和 j , i 的值被隔离,在闭包外不能被修改,改变 j 的值以后,再次调用 a ,发现结果是修改过的值。在变量 a 指向的闭包函数中,只有内部的匿名函数才能访问变量 i ,而无法通过其他途径访问到,因此保证了 i 的安全性。


2.错误处理

2.1 error接口

Go语言引入了一个关于错误处理的标准模式,即 error 接口,该接口的定义如下:

type error interface {

    Error() string

}

创建error通常如下:

var e error = errors.New("...")//需要使用使用errors包


对于大多数函数,如果要返回错误,大致上都可以定义为如下模式,将 error 作为多种返回

值中的最后一个,但这并非是强制要求:

func Foo(param int)(res int,err error){

    //....

}


调用时的代码建议按如下方式处理错误情况:

1

2

n, err := Foo(0)

if err != nil {

// 错误处理

} else {

// 使用返回值n

}


2.2 defer关键字

Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回。特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题。

func ReadWrite() bool {

    file.Open("file")

// 做一些工作

    if failureX {

        file.Close()

        return false

    }

    if failureY {

        file.Close()

        return false

    }

    file.Close()

    return true

}

我们看到上面有很多重复的代码,Go的defer有效解决了这个问题。使用它后,不但代码量减少了很多,而且程序变得更优雅。

func ReadWrite() bool {

    file.Open("file")

defer file.Close() //保证资源正常关闭

    if failureX {

        return false

    }

    if failureY {

        return false

    }

    return true

}


如果有很多调用defer,那么defer是采用后进先出模式

1

2

for i := 0; i < 5; i++ {

defer fmt.Printf("%d ", i) //输出结果:4 3 2 1 0

}


defer有点类似java中的try{}finall{}


2.3 panic和recover函数


Go语言有2个内置的函数panic()和recover(),用以报告和捕获运行时发生的程序错误,与error不同,panic和recover一般用在函数内部。一定要注意不要滥用panic和recover,可能会导致性能问题,一般只在未知输入和不可靠请求时使用。Go语言的错误处理流程:当一个函数在执行过程中出现了异常或遇到 panic(),正常语句就会立即终止,然后执行 defer 语句,再报告异常信息,最后退出 goroutine。如果在defer中使用了recover()函数,则会捕获错误信息,使该错误信息终止报告。如下示例,例子来自网络

package main

import (

"log"  //log包

"strconv" //字符转换包

)

//捕获因未知输入导致的程序异常

func catch(nums ...int) int {

    defer func() {

//recover()可以捕获运行时发生的异常,避免异常时程序直接over,通常用在defer函数内

        if r := recover(); r != nil {

log.Println("[E]", r) //将捕获的异常信息通过log打印,而不会导致程序挂掉

        }

    }()

    return nums[1] * nums[2] * nums[3] //index out of range

}

//主动抛出 panic,不推荐使用,可能会导致性能问题

func toFloat64(num string) (float64, error) {

    defer func() {

        if r := recover(); r != nil {

            log.Println("[W]", r)

        }

    }()

    if num == "" {

panic("param is null") //主动抛出 panic

    }

    return strconv.ParseFloat(num, 10)

}


func main() {

    catch(2, 8)

    toFloat64("")

}


运行结果:

2016/03/26 20:16:03 [E] runtime error: index out of range

2016/03/26 20:16:03 [W] param is null

最后补充下nil的介绍:

golang的nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。

nil是预先说明的标识符,也即通常意义上的关键字。在golang中,nil只能赋值给指针、

channel、func、interface、map或slice类型的变量。如果未遵循这个规则,则会引发panic。

高能预警,兄弟连教育区块链直播课程8月持续火爆来袭!

原价1188元的12节区块链进阶课程,现仅需1元!

还可免费领取《Go语言基础实战项目开发》与《Go语言高级实战项目开发》教材两本!!

限时限量!!先到先得!!

http://www.ydma.cn/open/course/24



有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:兄弟连区块链培训

查看原文:兄弟连Go语言培训分享闭包和错误处理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

894 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传