1、系统自己抛异常

//go语言抛异常

func test3_1()  {
l := [5] int {0,1,2,3,4} var index int = 6 fmt.Println(l)
l[index] = 6 }

测试结果

	//test3_1()
//panic这个关键字,这是系统自己抛的异常
//panic: runtime error: index out of range

 

2、用户抛异常,使用panic关键字

func test3_2(s float64) (m float64)  {
if s < 0 {
panic("该参数为半径,不能小于0") }else {
return 3.14 * s * s
}
}

测试结果

	//正常的参数,不会抛异常
//res := test3_2(3.6)
//fmt.Println(res)
//40.6944 //res := test3_2(-3.6)
//fmt.Println(res)
//panic: 该参数为半径,不能小于0

3、使用defer+recover捕获函数执行过程中的异常并打印

func test3_3() {
defer func() {
//这个recover会捕获函数执行的异常的错误信息,我们这里的例子是执行test3_2这个函数报错,使用panic抛出了异常,这里recover就会接受到这个异常,然后打印出来
err := recover()
if err != nil {
fmt.Println(err,"1111")
}
}()
test3_2(-2.34)
fmt.Println("这里是函数3")
}

测试结果

	//test3_3()
//该参数为半径,不能小于0 1111

我们看到“这里是函数3”这句话没有打印,因为上面的函数执行出错了,就直接执行defer语句了

4、defer+recover用法2

func test3_3() {
defer func() {
//这个recover会捕获函数执行的异常的错误信息,我们这里的例子是执行test3_2这个函数报错,使用panic抛出了异常,这里recover就会接受到这个异常,然后打印出来
err := recover()
if err != nil {
fmt.Println(err,"1111")
}
}()
test3_2(-2.34)
fmt.Println("这里是函数3")
} func test3_4() {
test3_3()
fmt.Println("这里是函数4")
}

测试结果

	//test3_4()
//该参数为半径,不能小于0 1111
//这里是函数4

这里打印了“这里是函数4”,主要是因为test3_3这个函数执行本身没有报错

5、使用errors.NEW返回异常,并捕获打印

//接受异常
func test3_5(b float64) (m float64,e error) {
if b < 0 {
e = errors.New("傻屌,半径不能为负数")
return
}else {
m = b * b *3.14
return
}
}

测试结果

	m,e := test3_5(3.21)
fmt.Println(m,e)
//32.354874 <nil> m1,e1 := test3_5(-3.21)
fmt.Println(m1,e1)
//0 傻屌,半径不能为负数

Go 错误处理

Go 语言通过内置的错误接口提供了非常简单的错误处理机制。

error类型是一个接口类型,这是它的定义:

type error interface {
Error() string
}

我们可以在编码中通过实现 error 接口类型来生成错误信息。

函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:

func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现
}

在下面的例子中,我们在调用Sqrt的时候传递的一个负数,然后就得到了non-nil的error对象,将此对象与nil比较,结果为true,所以fmt.Println(fmt包在处理error时会调用Error方法)被调用,以输出错误,请看下面调用的示例代码:

result, err:= Sqrt(-1)

if err != nil {
fmt.Println(err)
}
package main

import (
"fmt"
) // 定义一个 DivideError 结构
type DivideError struct {
dividee int
divider int
} // 实现 `error` 接口
func (de *DivideError) Error() string {
strFormat := `
Cannot proceed, the divider is zero.
dividee: %d
divider: 0
`
return fmt.Sprintf(strFormat, de.dividee)
} // 定义 `int` 类型除法运算的函数
func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
if varDivider == 0 {
dData := DivideError{
dividee: varDividee,
divider: varDivider,
}
errorMsg = dData.Error()
return
} else {
return varDividee / varDivider, ""
} } func main() { // 正常情况
if result, errorMsg := Divide(100, 10); errorMsg == "" {
fmt.Println("100/10 = ", result)
}
// 当被除数为零的时候会返回错误信息
if _, errorMsg := Divide(100, 0); errorMsg != "" {
fmt.Println("errorMsg is: ", errorMsg)
} }

执行以上程序,输出结果为:

100/10 =  10
errorMsg is:
Cannot proceed, the divider is zero.
dividee: 100
divider: 0

这里应该介绍一下 panic 与 recover,一个用于主动抛出错误,一个用于捕获panic抛出的错误。

概念

panic 与 recover 是 Go 的两个内置函数,这两个内置函数用于处理 Go 运行时的错误,panic 用于主动抛出错误,recover 用来捕获 panic 抛出的错误。

  • 引发panic有两种情况,一是程序主动调用,二是程序产生运行时错误,由运行时检测并退出。
  • 发生panic后,程序会从调用panic的函数位置或发生panic的地方立即返回,逐层向上执行函数的defer语句,然后逐层打印函数调用堆栈,直到被recover捕获或运行到最外层函数。
  • panic不但可以在函数正常流程中抛出,在defer逻辑里也可以再次调用panic或抛出panicdefer里面的panic能够被后续执行的defer捕获。
  • recover用来捕获panic,阻止panic继续向上传递。recover()defer一起使用,但是defer只有在后面的函数体内直接被掉用才能捕获panic来终止异常,否则返回nil,异常继续向外传递。

例子1

//以下捕获失败
defer recover()
defer fmt.Prinntln(recover)
defer func(){
func(){
recover() //无效,嵌套两层
}()
}() //以下捕获有效
defer func(){
recover()
}() func except(){
recover()
}
func test(){
defer except()
panic("runtime error")
}

例子2

多个panic只会捕捉最后一个:

package main
import "fmt"
func main(){
defer func(){
if err := recover() ; err != nil {
fmt.Println(err)
}
}()
defer func(){
panic("three")
}()
defer func(){
panic("two")
}()
panic("one")
}

使用场景

一般情况下有两种情况用到:

  • 程序遇到无法执行下去的错误时,抛出错误,主动结束运行。
  • 在调试程序时,通过 panic 来打印堆栈,方便定位错误。

在看一个事例

if result, errorMsg := Divide(100, 10); errorMsg == "" {
fmt.Println("100/10 = ", result)
} if _, errorMsg := Divide(100, 0); errorMsg != "" {
fmt.Println("errorMsg is: ", errorMsg)
}

上面的事例等价于下面的事例

result, errorMsg := Divide(100,10)
if errorMsg == ""{
fmt.Println("100/10 = ", result)
} result, errorMsg = Divide(100,0)
if errorMsg != ""{
fmt.Println("errorMsg is: ", errorMsg)
}

fmt.Println 打印结构体的时候,会把其中的 error 的返回的信息打印出来

type User struct {
username string
password string
} func (p *User) init(username string ,password string) (*User,string) {
if ""==username || ""==password {
return p,p.Error()
}
p.username = username
p.password = password
return p,""} func (p *User) Error() string {
return "Usernam or password shouldn't be empty!"}
} func main() {
var user User
user1, _ :=user.init("","");
fmt.Println(user1)
}

结果如下

Usernam or password shouldn't be empty!

 

字符串操作

package main

import (
"fmt"
"strconv"
) //字符串转换
//Append系列函数,把整数等转换为字符串,添加到现有的字节数组中
//Format系列函数,把其他类型的转换为字符串
//Parse系列函数,把字符串转换为其他类型
func main() {
str := make([]byte,0,100) //10是十进制的意思
str = strconv.AppendInt(str,456,16)
str = strconv.AppendBool(str,false)
str = strconv.AppendQuote(str,"abc")
fmt.Println(string(str))
}

  

go语言的错误处理的更多相关文章

  1. C语言常见错误中英文对照表

    C语言常见错误中英文对照表(网络搜索及经验积累不断更新中) 常见错误中英文对照表 fatal error C1003:  error count exceeds number; stopping co ...

  2. [日常] Go语言圣经-错误,函数值习题

    Go语言圣经-错误 1.panic异常.panic是来自被调函数的信号,表示发生了某个已知的bug 2.任何进行I/O操作的函数都会面临出现错误的可能 3.错误是软件包API和应用程序用户界面的一个重 ...

  3. 如何处理C++构造函数中的错误——兼谈不同语言的错误处理

    用C++写代码的时候总是避免不了处理错误,一般来说有两种方式,通过函数的返回值或者抛出异常.C语言的错误处理一律是通过函数的返回值来判断的,一般是返回0.NULL或者-1表示错误,或者直接返回错误代码 ...

  4. 常见C语言编译错误解析【转】

    C语言编译错误信息及说明1. 在函数 ‘transform’ 中:7: 错误:expected ‘;’ before ‘{’ token    解释:‘{’之前的某个语句缺少分号‘;’: 2. 在函数 ...

  5. 【Go语言】错误与异常处理机制

    ①error接口 Go语言中的error类型实际上是抽象了Error()方法的error接口 type error interface { Error() string } Go语言使用该接口进行标准 ...

  6. 常见C语言内存错误

    前言 C语言强大的原因之一在于几乎能掌控所有的细节,包括对内存的处理,什么时候使用内存,使用了多少内存,什么时候该释放内存,这都在程序员的掌控之中.而不像Java中,程序员是不需要花太多精力去处理垃圾 ...

  7. 多语言业务错误日志收集监控工具Sentry 安装与使用

    Sentry 是一个实时事件日志记录和汇集的平台.其专注于错误监控以及提取一切事后处理所需信息而不依赖于麻烦的用户反馈. Sentry是一个日志平台, 它分为客户端和服务端,客户端(目前客户端有Pyt ...

  8. Go 语言基础——错误处理

    #### 学习目标 掌握错误处理 掌握自定义错误处理 掌握defer关键字的使用 ------ #### 错误处理 GO没有异常处理机制 Go语言引入了一个关于错误处理的标准模式,即error接口,该 ...

  9. vs2017- C语言- winsocket- 链接错误 LNK2019

    错误介绍 操作系统:windows10 IDE:vs2017 语言:C语言 项目内容简介:编写一个双人网络海战棋对战游戏 错误类型:链接错误 LNK2019 解决方案:程序需要用到ws2_32.lib ...

随机推荐

  1. 信道估计之LS

    在无线通信系统中,系统的性能主要受到无线信道的制约.基站和接收机之间的传播路径复杂多变,从简单的视距传输到受障碍物反射.折射.散射影响的传播.在无线传输环境中,接收信号会存在多径时延,时间选择性衰落和 ...

  2. spring data jpa 操作pipelinedb 的continuous view 与stream

    一. 由于pipelinedb是postgreSQL的扩展,因此相关依赖于配置都合集成postgreSQL是一样的. springboot + spring data jpa + postgreSQL ...

  3. 牛客练习赛32B Xor Path (树形dp)

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 给定一棵n个点的树,每个点有权值.定义表示 ...

  4. tune kubernetes eviction parameter

    Highlight 本文会介绍kubernetes中关于集群驱逐的相关参数, 合理设置驱逐速率的考虑因素, 但是不会涉及node层面资源的驱逐阈值的设置. Basic 在kubernetes中, 如果 ...

  5. Spring Cloud进阶之路 | 二:服务提供者(discovery)

    1 创建父项目 以前文所述,以spring boot 2.1.7.RELEASE为基,spring cloud版本为Greenwich.SR2,spring cloud alibaba版本为2.1.0 ...

  6. python的memory_profiler模块使用

    本文主要介绍了python内存分析工具: memory_profiler,可以展示每一行代码执行所增加的内存,方便做内存调优和排除bug memory_profiler是第三方模块,需要安装才能使用 ...

  7. JavaScript图形实例:四瓣花型图案

    设有坐标计算公式如下: X=L*(1+SIN(4α))*COS(α) Y=L*(1+SIN(4α))*SIN(α) 用循环依次取α值为0~2π,计算出X和Y,在canvas画布中对坐标位置(X,Y)描 ...

  8. 【数据库】SQLite3常用函数

    版权声明:本文为博主原创文章,转载请注明出处. https://www.cnblogs.com/YaoYing/ SQLite3常用函数 打开数据库 函数原型: int sqlite3_open(co ...

  9. Beeline里面执行hive脚本 函数nvl2()与replace()报错

    Beeline里面执行hive脚本函数nvl2()与replace()报错 写脚本的时候是在impala里面执行的,都正常,但是转换为调度的时候是在beeline里面执行的 就会有问题了. 详情如下: ...

  10. Java基础语法02-流程控制-if-switch-for-while

    流程控制语句 顺序结构 任何编程语言中最常见的程序结构就是顺序结构.顺序结构就是程序从上到下逐行地执行,中间没有任何判断和跳转. 分支结构 if(条件表达式){ 语句体;} 执行流程 首先判断条件表达 ...