Go语言的函数可以一次返回多个结果。这就为我们温和地报告错误提供了语言级别的支持。
func readFile(path string) ([]byte, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
return ioutil.ReadAll(file)
}
函数readFile有两个结果声明。第二个结果声明的类型是error。
error是Go语言内置的一个接口类型。它的声明是这样的:
type error interface {
Error() string
}
errors.New是一个很常用的函数。在Go语言标准库的代码包中有很多由此函数创建出来的错误值。
if path == "" {
return nil, errors.New("The parameter is invalid!")
}

panic

panic可被意译为运行时恐慌。因为它只有在程序运行的时候才会被“抛出来”。
内建函数panic可以让我们人为地产生一个运行时恐慌。
不过,这种致命错误是可以被恢复的,在Go语言中,内建函数recover就可以做到这一点。
内建函数panic和recover是天生的一对。
前者用于产生运行时恐慌,而后者用于“恢复”它。
不过要注意,recover函数必须要在defer语句中调用才有效。
因为一旦有运行时恐慌发生,当前函数以及在调用栈上的所有代码都是失去对流程的控制权。
只有defer语句携带的函数中的代码才可能在运行时恐慌迅速向调用栈上层蔓延时“拦截到”它。
defer func() {
if p := recover(); p != nil {
fmt.Printf("Fatal error: %s\n", p)
}
}()
我们调用了recover函数。该函数会返回一个interface{}类型的值。
interface{}代表空接口。
Go语言中的任何类型都是它的实现类型。
把这个值赋给了变量p。如果p不为nil,那么就说明当前确有运行时恐慌发生。
这时我们需根据情况做相应处理。
注意,一旦defer语句中的recover函数调用被执行了,运行时恐慌就会被恢复,不论我们是否进行了后续处理。
所以,我们一定不要只“拦截”不处理。
反观panic函数。
该函数可接受一个interface{}类型的值作为其参数。
也就是说,我们可以在调用panic函数的时候可以传入任何类型的值。
不过,我建议大家在这里只传入error类型的值。
这样它表达的语义才是精确的。
更重要的是,当我们调用recover函数来“恢复”由于调用panic函数而引发的运行时恐慌的时候,
得到的值正是调用后者时传给它的那个参数。
因此,有这样一个约定是很有必要的。
运行时恐慌代表程序运行过程中的致命错误。我们只应该在必要的时候引发它。
人为引发运行时恐慌的方式是调用panic函数。
recover函数是我们常会用到的。
因为在通常情况下,我们肯定不想因为运行时恐慌的意外发生而使程序崩溃。
最后,在“恢复”运行时恐慌的时候,大家一定要注意处理措施的得当。
package main

import (
"fmt"
) func testa(num int) {
defer func() {
//返回错误信息
if err := recover(); err != nil {//
fmt.Println(err)
}
}() var a []int
a[num] =
fmt.Println("normal")
} func main() {
testa()
}

go-异常处理-error-panic-recover的更多相关文章

  1. [Go] 如何正确地 抛出 错误 和 异常(error/panic/recover)?

    序言 错误 和 异常 是两个不同的概念,非常容易混淆.很多程序员习惯将一切非正常情况都看做错误,而不区分错误和异常,即使程序中可能有异常抛出,也将异常及时捕获并转换成错误.从表面上看,一切皆错误的思路 ...

  2. Go语言异常处理defer\panic\recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  3. Go的异常处理 defer, panic, recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  4. go panic recover 异常处理

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  5. Go语言中异常处理painc()和recover()的用法

    Go语言中异常处理painc()和recover()的用法 1.Painc用法是:用于抛出错误.Recover()用法是:将Recover()写在defer中,并且在可能发生panic的地方之前,先调 ...

  6. defer,panic,recover

    Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个 ...

  7. 探究 Go 源码中 panic & recover 有哪些坑?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/627 本文使用的go的源码1.17.3 前言 写这一篇文章的原因是 ...

  8. go语言defer panic recover用法总结

    defer defer是go提供的一种资源处理的方式.defer的用法遵循3个原则 在defer表达式被运算的同时,defer函数的参数也会被运算.如下defer的表达式println运算的同时,其入 ...

  9. defer, panic, recover使用总结

    1. defer : 延迟调用.多个defer,依次入栈,在函数即将退出时,依次出栈调用 package main import "fmt" func main() { defer ...

  10. go chapter 5 - 异常处理 error、panic、recover

    https://blog.csdn.net/tennysonsky/article/details/78946265 error(不中断).panic(中断).recover(拦截中断  类似于 ca ...

随机推荐

  1. All Of ACM

    数据结构和算法专栏,我会什么写什么  = = 不定时更新 一.数据结构 树状数组详解 线段树详解 二.算法 KMP算法 三.板子 我的代码模板 大整数模板 四.题解报告 几道STL题目(FJUT - ...

  2. python 虚拟环境下导入模块出现no matching modules 的解决办法

    问题原因:pip版本过低 解决办法:升级pip                             命令行为   python -m pip install -U pip

  3. Set集合、List集合

    集合体系:Collection.Map接口 存储数量不等的多个对象,不能存储基本数据类型,如存储基本数据类型会自动装箱 ======================================== ...

  4. 自己动手实现springboot配置(非)中心

    好久没写博客了,这段时间主要是各种充电,因为前面写的一些东西,可能大家不太感兴趣或者是嫌弃没啥技术含量,所以这次特意下了一番功夫.这篇博客其实我花了周末整整两天写好了第一个版本,已经开源出去了,同样是 ...

  5. 修改tomcat 使用的JVM的内存

    一,前言 在文章让tomcat使用指定JDK中,我让tomcat成功使用了我指定的JDK1.8,而不是环境变量中配置的JDK10.本篇文章我们就来探讨一下怎么设置tomcat使用的JVM的内存. 为什 ...

  6. mysql5.6.27压缩版安装配置指南【个人总结】

      1..下载准备压缩包   360云盘下载地址: https://yunpan.cn/cPKyugkUcDEmP  访问密码 375b   2.解压缩,将压缩版解压到D盘 D:\mysql-5.6. ...

  7. java、if判断和循环

    一.选择.循环语法    选择        if            if(表达式)语句A:                如果表达式的值是真的,就会执行语句A,否则不执行             ...

  8. Centos6安装MySQL5.7(yum方式)

    1. 下载并安装用来配置mysql的yum源的rpm包 # 下载 wget http://repo.mysql.com/mysql57-community-release-el6-10.noarch. ...

  9. Spring MVC-从零开始-@RequestMapping 注解method属性

    1.@RequestMapping 处理 HTTP 的各种方法(GET, PUT, POST, DELETE  PATCH) package com.jt; import org.springfram ...

  10. Spring MVC-从零开始-第一个控制器(不考虑命名规范)

    1.目录结构 (log4j.properties.mybatis-config.xml可忽略) 2.配置web.xml文件 <?xml version="1.0" encod ...