【Go必知必会】错误和异常、CGO、fallthrough

简介: 在一个 switch 块内,每个 case 无需声明 break 来终止,如果想顺序执行使用fallthrough;如果我们想强制执行满足条件case的后一个case,也可以通过设置fallthrough的方式:

fallthrough


在一个 switch 块内,每个 case 无需声明 break 来终止,如果想顺序执行使用fallthrough

如果我们想强制执行满足条件case的后一个case,也可以通过设置fallthrough的方式:


代码示例


package main
import "fmt"
func main() {
    switch {
    case false:
            fmt.Println("false1")
            fallthrough
    case true:
            fmt.Println("true1")
            fallthrough
    case false:
            fmt.Println("false2")
            fallthrough
    case true:
            fmt.Println("true2")
    case false:
            fmt.Println("false3")
            fallthrough
    default:
            fmt.Println("default case")
    }
}


思考一下上面代码的执行结果是什么?


执行结果


微信图片_20221113152909.jpg


注意:在一个switch块内,都建议包含一个 default 语句并且放在最后,即使它什么代码也没有。

延伸知识点:在select块中,default能避免死锁问题。


CGO


CGO是调用C代码模块,静态库和动态库。

CGO是C语言和Go语言之间的桥梁,原则上无法直接支持C++的类。CGO不支持C++语法的根本原因是C++至今为止还没有一个二进制接口规范(ABI)。CGO只支持C语言中值类型的数据类型,所以我们是无法直接使用C++的引用参数等特性的。


错误&异常


错误指的是可能出现问题的地方出现了问题,比如打开一个文件时失败,这种情况在人们的意料之中

异常指的是不应该出现问题的地方出现了问题,比如引用了空指针,这种情况在人们的意料之外。

可见,错误是业务过程的一部分,而异常不是 。


处理错误:error


Golang中引入error接口类型作为错误处理的标准模式,如果函数要返回错误,则返回值类型列表中肯定包含error。error处理过程类似于C语言中的错误码,可逐层返回,直到被处理。


处理异常:panic&recover


Golang中引入两个内置函数panic和recover来触发和终止异常处理流程,同时引入关键字defer来延迟执行defer后面的函数。


panic&defer


当数组越界、访问非法空间或者我们直接调用panic时,panic会停掉当前正在执行的程序,包括所有协程,比起exit直接退出,panic的退出更有秩序,他会他会先处理完当前goroutine已经defer挂上去的任务,执行完毕后再退出整个程序。

而defer的存在,让我们有更多的选择,比如在defer中通过recover截取panic,从而达到try…catch的效果

panic还可以接收一个参数,通常是字符串类型错误信息,执行到panic时,他会打印这个字符串和触发他的调用战。

当然,我们在写代码时要注意,不是所有的异常都能被捕获到的,向fatal error 和runtime.throw 都是不能被recover的


defer执行顺序


你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反。


总结


当程序运行时,如果遇到引用空指针、下标越界或显式调用panic函数等情况,则先触发panic函数的执行,然后调用延迟函数。调用者继续传递panic,因此该过程一直在调用栈中重复发生:函数停止执行,调用延迟执行函数等。如果一路在延迟函数中没有recover函数的调用,则会到达该协程的起点,该协程结束,然后终止其他所有协程,包括主协程(类似于C语言中的主线程,该协程ID为1)。


对比Java、C++


错误和异常从Golang机制上讲,就是error和panic的区别。很多其他语言也一样,比如C++/Java,没有error但有errno,没有panic但有throw。


错误异常互相转换


Golang错误和异常是可以互相转换的:


  1. 错误转异常,比如程序逻辑上尝试请求某个URL,最多尝试三次,尝试三次的过程中请求失败是错误,尝试完第三次还不成功的话,失败就被提升为异常了。
  2. 异常转错误,比如panic触发的异常被recover恢复后,将返回值中error类型的变量进行赋值,以便上层函数继续走错误处理流程
相关文章
|
4月前
|
Go 开发者
Go语言中的错误处理与异常机制:实践与最佳策略
【2月更文挑战第7天】Go语言以其独特的错误处理机制而闻名,它鼓励显式错误检查而不是依赖于异常。本文将探讨错误处理与异常机制在Go语言中的实际应用,并分享一些最佳实践,帮助开发者编写更加健壮和易于维护的Go代码。
|
Java Go
一文搞懂Go语言错误处理【异常捕获、异常抛出】
一文搞懂Go语言错误处理【异常捕获、异常抛出】
389 0
一文搞懂Go语言错误处理【异常捕获、异常抛出】
|
Linux Go vr&ar
Golang cgo:如何在Go代码中调用C语言代码?
Golang cgo:如何在Go代码中调用C语言代码?
779 0
Golang cgo:如何在Go代码中调用C语言代码?
|
存储 数据可视化 Go
记一次线上Go服务内存占用异常问题排查
记一次线上Go服务内存占用异常问题排查
467 0
记一次线上Go服务内存占用异常问题排查
|
Java Linux Serverless
go 语言高级特性--CGO的使用
cgo 是 go 语言里面的一个特性,属于 go 的高级用法,我们可以使用 cgo 来实现 go 语言调用 c 语言程序。
706 0
go 语言高级特性--CGO的使用
|
Cloud Native 测试技术 Go
cgo 机制 - 从 c 调用 go
去年刚学 go 语言的时候,写了这篇 cgo 实现机制[1] ,介绍了 cgo 的基本情况。主要介绍的是 `go=>c` 这个调用方式,属于比较浅的层次。随着了解的深入,发现 `c=>go` 的复杂度又高了一级,所以有了这篇文章。
cgo 机制 - 从 c 调用 go
|
SQL Ubuntu Go
go在ubuntu交叉编译windows应用.cgo错误
交叉编译cgo项目是出了名的困难,也是众所周知的GoReleaser的limitation。我建议您查看一下cgo cookbook,如果您还没有这样做的话。
1356 0
|
消息中间件 Go API
一次Go应用上云后线上性能异常排查
先说结论:资源使用不合理导致机器性能浪费起因:线上某应用告警机器负载及资源占用异常,登陆机器查看进程vmstat发现idle比较低线上是一个Go的应用,而且已经开启了PProf,索性就利用该工具分析一下性能瓶颈在哪PProf如何使用不在本文赘述,经分析初步断定在`ReceiveMessage`这个接口该方法是阿里云的SDK三方包提供的,按道理三方包不会出问题通过代码分析出send函数本质是通过一个
一次Go应用上云后线上性能异常排查
go 如何捕获异常
go 如何捕获异常
253 0