Go语言开发(七)、Go语言错误处理

Go语言开发(七)、Go语言错误处理

一、defer延迟函数

1、defer延迟函数简介

defer在声明时不会立即执行,而是在函数return后,再按照FILO(先进后出)的原则依次执行每一个defer,一般用于异常处理、释放资源、清理数据、记录日志等。
每次defer语句执行时,defer修饰的函数的返回值和参数取值会照常进行计算和保存,但是defer修饰的函数不会执行。等到上一级函数返回前,会按照defer的声明顺序倒序执行全部defer的函数。defer所修饰函数的任何返回值都会被丢弃。
如果一个defer所修饰函数的值为nil,则defer的函数会在函数执行时panic(异常),而不会在defer语句执行时panic。defer所修饰函数的上一级函数即使抛出异常,defer所修饰函数也会被执行的,确保资源被合法释放。
defer延迟函数使用示例如下:

package main

import "fmt"

func deferTest(){
   defer fmt.Println(1)
   defer fmt.Println(2)
   fmt.Println(3)
}

func main() {
   deferTest()//3,2,1
}

2、defer延迟函数应用

A、简化资源回收

mu.Lock()
defer mu.Unlock()

defer?有一定的开销, 为了节省性能可以避免使用的defer?
B、捕获panic异常
Go语言中,panic用于抛出异常,,recover用于捕获异常。
recover只能在defer语句中使用,直接调用recover是无效的。

package main

import "fmt"

func deferRecover(){
   defer func () {
      if r := recover(); r != nil {
         fmt.Println("recover")
      }
   }()
   fmt.Println("exception will be happen")
   panic("exception has happped.")
   fmt.Println("return normally")
}

func main() {
   deferRecover()
}

C、修改返回值
defer可以用于在?return?后修改函数的返回值。

package main

import "fmt"

func deferReturn(a,b int)(sum int){
   defer func(){
      sum += 100
   }()
   sum = a + b
   return sum
}

func main() {
   sum := deferReturn(1,6)
   fmt.Println(sum)//107
}

D、安全回收资源

func set(mu *sync.Mutex, arr []int, i, v int) {
   mu.Lock()
   defer mu.Unlock()
   arr[i] = v
}

如果运行时抛出切片越界异常,可以保证mu.Unlock()被调用。

二、错误处理

1、错误处理简介

Go语言通过内置的错误接口提供了简单的错误处理机制。
error类型是一个接口类型,定义如下:

type error interface {
    Error() string}

Golang中引入error接口类型作为错误处理的标准模式,如果函数要返回错误,则返回值类型列表中肯定包含error。

2、错误处理使用

package main

import (
   "fmt"
   "errors"
)

//定义一个DivideError类型
type DivideError struct {
   dividee int
   divider int
}
//实现error接口
func (err *DivideError) Error() error{
   strFormat := `Cannot proceed, the divider is zero.
dividee: %d
divider: 0`
   return errors.New(fmt.Sprintf(strFormat, err.dividee))
}
//定义除法运算
func divide(vardividee int, vardivider int)(result int, errmsg error){
   if vardivider == 0{
      divideErr := DivideError{
         dividee:vardividee,
         divider:vardivider,
      }
      errmsg = divideErr.Error()
      return 0,errmsg
   }else{
      return vardividee/vardivider,nil
   }
}

func main() {
   //正常情况
   if result, err := divide(100, 10); err != nil{
      fmt.Println(err)
   }else{
      fmt.Println("100/10 = ", result)
   }
   //当被除数为零的时候会返回错误信息
   if _, errorMsg := divide(100, 0); errorMsg != nil{
      fmt.Println(errorMsg)
   }
}

三、异常处理

1、异常处理简介

Go使用panic()函数抛出异常,在defer语句中调用recover()函数捕获异常。

func panic(interface{})//接受任意类型参数 无返回值
func recover() interface{}//可以返回任意类型 无参数

panic()是一个内置函数,可以中断原有的控制流程,进入一个panic流程中。当函数F调用panic,函数F的执行被中断,但F中的延迟函数(必须是在panic前的已加载的defer)会正常执行,然后F函数逐层向上返回,直到发生panic的goroutine中所有调用的函数返回,此时程序退出。异常可以直接调用panic产生,也可以由运行时错误产生,例如访问越界的数组。
recover()是一个内置函数,可以让进入panic流程中的goroutine恢复过来。recover仅在延迟函数中有效。在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。如果当前的goroutine陷入panic,调用recover可以捕获到panic的输入值,并且恢复正常的执行。
一般情况下,recover()应该在一个使用defer关键字的函数中执行以有效截取错误处理流程。如果没有在发生异常的goroutine中明确调用恢复过程(使用recover关键字),会导致goroutine所属的进程打印异常信息后直接退出。

2、异常处理使用示例

package main

import (
   "errors"
   "fmt"
)

//定义一个DivideError类型
type DivideError struct {
   dividee int
   divider int
}
//实现error接口
func (err *DivideError) Error() error{
   strFormat := `Cannot proceed, the divider is zero.
dividee: %d
divider: 0`
   return errors.New(fmt.Sprintf(strFormat, err.dividee))
}

//定义除法运算
func divide(dividee int, divider int)(result int){
   defer func() {
      if r := recover();r != nil{
         divideErr := DivideError{
            dividee:dividee,
            divider:divider,
         }
         fmt.Println(divideErr.Error())
      }
   }()
   result = dividee/divider
   return result
}

func main() {
   a := divide(100,0)
   fmt.Println(a)
}

原文地址:http://blog.51cto.com/9291927/2130707

时间: 2024-10-11 05:43:47

Go语言开发(七)、Go语言错误处理的相关文章

001-iOS开发前奏-C语言笔记

学习目标 1.[了解]操作系统 2.[了解]应用软件 3.[了解]操作系统的分类和市场占有份额 4.[了解]iOS操作系统 5.[了解]应用软件开发的分类 6.[了解]UNIX常用命令 7.[掌握]如何开发第一个C语言程序 一.操作系统 我们的计算机是由很多种硬件设备组成的,比如CPU.内存.硬盘.网卡.主板.声卡.......如果计算机只是仅仅有这些硬件设备,这样能不能正常使用? CPU:负责计算.处理数据 内存:存储数据 (临时) 硬盘:存储数据 (永久) 网卡:接收.发送网络数据 声卡:输

「C语言」Windows+EclipseCDT下的C语言开发环境准备

之前写过一篇 「C语言」在Windows平台搭建C语言开发环境的多种方式 ,讨论了如何在Windows下用DEV C++.EclipseCDT.VisualStudio.Sublime Test.Clion等IDE/编辑器搭建C语言开发环境,但也只是点到为止的介绍,对每一个开发环境的选择没有详细的步骤与过程: 这次借助C语言期末课程设计文档上介绍用Eclipse开发C语言的时机,逐步图文论证如何用Eclipse从安装到输出自己的第一个C语言Hello World: 欢迎探讨,欢迎互粉: 目录:

IOS开发系列--C语言之生存储方式和作用域

概述 基本上每种语言都要讨论这个话题,C语言也不例外,因为只有你完全了解每个变量或函数存储方式.作用范围和销毁时间才可能正确的使用这门语言.今天将着重介绍C语言中变量作用范围.存储方式.生命周期.作用域和可访问性. 变量作用范围 存储方式 可访问性 变量作用范围 在C语言中变量从作用范围包括全局变量和局部变量.全局变量在定义之后所有的函数中均可以使用,只要前面的代码修改了,那么后面的代码中再使用就是修改后的值:局部变量的作用范围一般在一个函数内部(通常在一对大括号{}内),外面的程序无法访问它,

Go语言开发(二)、Go语言基础

Go语言开发(二).Go语言基础 一.Go语言程序结构 Go语言程序基本结构如下:A.包声明B.引入包C.函数D.变量E.语句 & 表达式F.注释 package main //包声明 import "fmt" //引入包 func main(){ //main函数 //打印Hello World fmt.Print("Hello World!") } 二.Go语言基础语法 1.Go语言标记 Go语言程序由多个标记组成,可以是关键字.标识符.常量.字符串.符

Go语言开发学习教程

Go语言开发学习教程 Go语言开发学习教程目录如下: Go语言开发(一).Go语言简介http://blog.51cto.com/9291927/2126775Go语言开发(二).Go语言基础http://blog.51cto.com/9291927/2127825Go语言开发(三).Go语言内置容器http://blog.51cto.com/9291927/2129969Go语言开发(四).Go语言面向对象http://blog.51cto.com/9291927/2130132Go语言开发(

C#语言开发规范-ching版

学习C#之初,始终不知道怎么命名比较好,很多时候无从命名,终于有一天我整理了一份命名规范文档,自此我就是按照这个命名规范书写代码,整洁度无可言表,拙劣之处请大家斧正,愚某虚心接受,如有雷同,不胜荣幸 C#语言开发规范 作者ching 1.  命名规范 a) 类 [规则1-1]使用Pascal规则命名类名,即首字母要大写. eg: Class Test { ... } [规则1-2]使用能够反映类功能的名词或名词短语命名类. [规则1-3]不要使用“I”.“C”.“_”等特定含义前缀. [规则1-

Swift 新语言开发

全书目录: 一.Welcome to Swift 二.Language Guide 三.Language Reference /* 译者的废话: 几个小时前熬夜看了WWDC,各种激动,今年很有料啊!当看到Swift出来的时候,瞬间傻眼,又要学习新语言了.这篇文章来自苹果官方的<The Swift Programming Language>一书,500页左右,在苹果官网有下载.Swift大家都没实际用过,本翻译一定是有各种错漏的,各位多多包涵,我会不断更新修正的. --(博客园.新浪微博)葛布林

C语言开发工具

常用的C语言开发工具有很多,每个开发工具所支持的库函数和对标准的实现都有差异.不过,对于我这样得初学者,可以忽略这些细节,选择一款使用广泛.上手容易的开发工具才是王道.在网上找了一下,Windows平台下推荐Visual C++ 6.0,Linux平台下推荐使用GCC,由于本人用得是unix系同当让用GCC啦. 1) Windows平台下推荐Visual C++ 6.0 Visual C++ 6.0简称VC或者VC6.0,是微软1989年推出的一款C/C++编译器,界面友好,调试功能强大.VC6

在Windows平台搭建C语言开发环境的多种方式

新接触C语言,如何进行C语言开发环境的搭建值得思考并整理 注:本文知识来源于  Windows 平台搭建C语言集成开发环境 - 极客学院 一.在Windows平台配置GNU环境 二.在Windows平台使用Sublime Test开发C语言程序 三.在Windows平台使用VisualStudio开发C语言程序 四.在Windows平台搭建EclipseCDT集成开发环境 五.在Windows平台搭建Clion集成开发环境 一.在Windows平台配置GNU环境 GNU http://www.g