go语言笔记——多值函数,本质上和nodejs的回调很像,不过nodejs是回调的第一个参数是err,而golang里是第二个!
5.2 测试多返回值函数的错误
Go 语言的函数经常使用两个返回值来表示执行是否成功:返回某个值以及 true 表示成功;返回零值(或 nil)和 false 表示失败(第 4.4 节)。当不使用 true 或 false 的时候,也可以使用一个 error 类型的变量来代替作为第二个返回值:成功执行的话,error 的值为 nil,否则就会包含相应的错误信息(Go 语言中的错误类型为 error: var err error,我们将会在第 13 章进行更多地讨论)。这样一来,就很明显需要用一个 if 语句来测试执行结果;由于其符号的原因,这样的形式又称之为 comma,ok 模式(pattern)。
在第 4.7 节的程序 string_conversion.go 中,函数 strconv.Atoi 的作用是将一个字符串转换为一个整数。之前我们忽略了相关的错误检查:
anInt, _ = strconv.Atoi(origStr)
如果 origStr 不能被转换为整数,anInt 的值会变成 0 而 _ 无视了错误,程序会继续运行。
这样做是非常不好的:程序应该在最接近的位置检查所有相关的错误,至少需要暗示用户有错误发生并对函数进行返回,甚至中断程序。
我们在第二个版本中对代码进行了改进:
示例 1:
示例 5.3 string_conversion2.go
package main import (
"fmt"
"strconv"
) func main() {
var orig string = "ABC"
// var an int
var newS string
// var err error fmt.Printf("The size of ints is: %d\n", strconv.IntSize)
// anInt, err = strconv.Atoi(origStr)
an, err := strconv.Atoi(orig)
if err != nil {
fmt.Printf("orig %s is not an integer - exiting with error\n", orig)
return
}
fmt.Printf("The integer is %d\n", an)
an = an + 5
newS = strconv.Itoa(an)
fmt.Printf("The new string is: %s\n", newS)
}
这是测试 err 变量是否包含一个真正的错误(if err != nil)的习惯用法。如果确实存在错误,则会打印相应的错误信息然后通过 return 提前结束函数的执行。我们还可以使用携带返回值的 return 形式,例如 return err。这样一来,函数的调用者就可以检查函数执行过程中是否存在错误了。
习惯用法
value, err := pack1.Function1(param1)
if err != nil {
fmt.Printf("An error occured in pack1.Function1 with parameter %v", param1)
return err
}
// 未发生错误,继续执行:
由于本例的函数调用者属于 main 函数,所以程序会直接停止运行。
如果我们想要在错误发生的同时终止程序的运行,我们可以使用 os 包的 Exit 函数:
习惯用法
if err != nil {
fmt.Printf("Program stopping with error %v", err)
os.Exit(1)
}
(此处的退出代码 1 可以使用外部脚本获取到)
有时候,你会发现这种习惯用法被连续重复地使用在某段代码中。
当没有错误发生时,代码继续运行就是唯一要做的事情,所以 if 语句块后面不需要使用 else 分支。
示例 2:我们尝试通过 os.Open 方法打开一个名为 name 的只读文件:
f, err := os.Open(name)
if err != nil {
return err
}
doSomething(f) // 当没有错误发生时,文件对象被传入到某个函数中
doSomething
练习 5.1 尝试改写 string_conversion2.go 中的代码,要求使用 := 方法来对 err 进行赋值,哪些地方可以被修改?
示例 3:可以将错误的获取放置在 if 语句的初始化部分:
习惯用法
if err := file.Chmod(0664); err != nil {
fmt.Println(err)
return err
}
示例 4:或者将 ok-pattern 的获取放置在 if 语句的初始化部分,然后进行判断:
习惯用法
if value, ok := readData(); ok {
…
}
注意事项
如果您像下面一样,没有为多返回值的函数准备足够的变量来存放结果:
func mySqrt(f float64) (v float64, ok bool) {
if f < 0 { return } // error case
return math.Sqrt(f),true
}
func main() {
t := mySqrt(25.0)
fmt.Println(t)
}
您会得到一个编译错误:multiple-value mySqrt() in single-value context。
正确的做法是:
t, ok := mySqrt(25.0)
if ok { fmt.Println(t) }
注意事项 2
当您将字符串转换为整数时,且确定转换一定能够成功时,可以将 Atoi 函数进行一层忽略错误的封装:
func atoi (s string) (n int) {
n, _ = strconv.Atoi(s)
return
}
实际上,fmt 包(第 4.4.3 节)最简单的打印函数也有 2 个返回值:
count, err := fmt.Println(x) // number of bytes printed, nil or 0, error
当打印到控制台时,可以将该函数返回的错误忽略;但当输出到文件流、网络流等具有不确定因素的输出对象时,应该始终检查是否有错误发生(另见练习 6.1b)。
摘自:https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/05.2.md
go语言笔记——多值函数,本质上和nodejs的回调很像,不过nodejs是回调的第一个参数是err,而golang里是第二个!的更多相关文章
- Facebook图片存储系统Haystack——存小文件,本质上是将多个小文件合并为一个大文件来降低io次数,meta data里存偏移量
转自:http://yanyiwu.com/work/2015/01/04/Haystack.html 一篇14页的论文Facebook-Haystack, 看完之后我的印象里就四句话: 因为[传统文 ...
- Go语言笔记[实现一个Web框架实战]——EzWeb框架(一)
Go语言笔记[实现一个Web框架实战]--EzWeb框架(一) 一.Golang中的net/http标准库如何处理一个请求 func main() { http.HandleFunc("/& ...
- javascript 核心语言笔记 6 - 对象
对象是 JavaScript 的基本数据类型.是一种复合值:将很多值聚合在一起.对象可以看做是无序集合,每个属性都是一个名/值对.这种基本数据结构还有很多叫法,比如「散列」(hash).「散列表」(h ...
- 011-指针(上)-C语言笔记
011-指针(上)-C语言笔记 学习目标 1.[掌握]字符串常用函数 2.[掌握]指针变量的声明 3.[掌握]指针变量的初始化 4.[掌握]函数与指针 5.[掌握]指针的数据类型 6.[掌握]多级指针 ...
- 005-循环结构(上)-C语言笔记
005-循环结构(上)-C语言笔记 学习目标 1.[掌握]switch-case结构 2.[理解]case语句穿透 3.[理解]Xcode断点调试 4.[理解]while循环结构初体验 5.[掌握]w ...
- C++学习笔记----3.2 C++引用在本质上是什么,它和指针到底有什么区别
从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有 ...
- 瘋耔java语言笔记
一◐ java概述 1.1 ...
- R语言笔记
R语言笔记 学习R语言对我来说有好几个地方需要注意的,我觉得这样的经验也适用于学习其他的新的语言. 语言的目标 我理解语言的目标就是这个语言是用来做什么的,为什么样的任务服务的,也就是设计这个语言的动 ...
- Scala语言笔记 - 第一篇
目录 Scala语言笔记 - 第一篇 1 基本类型和循环的使用 2 String相关 3 模式匹配相关 4 class相关 5 函数调用相关 Scala语言笔记 - 第一篇 最近研究了下scala ...
随机推荐
- RocketMQ学习笔记(14)----RocketMQ的去重策略
1. Exactly Only Once (1). 发送消息阶段,不允许发送重复的消息 (2). 消费消息阶段,不允许消费重复的消息. 只有以上两个条件都满足情况下,才能认为消息是“Exactly O ...
- R中矩阵运算
# 数据产生 # rnorm(n, mean = 0, sd = 1) 正态分布的随机数(r 代表随机,可以替换成dnorm, pnorm, qnorm 作不同计算.r= random = 随机, d ...
- CAD如何设置系统变量
主要用到函数说明: MxDrawXCustomFunction::Mx_SetSysVar 设置系统变量.详细说明如下: 参数 说明 CString sVarName 系统变量名 Value 需要设置 ...
- 2018最新Python小白入门教程,30天学会Python
随着Python的技术的流行,Python在为人们带来工作与生活上带来了很多的便捷,因为Python简单,学起来快,也是不少新手程序员入门的首选语言.作为一名Python爱好者,我也想跟大家分享分享我 ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- 如何在 CentOS 7 上安装 Nginx
本文首发:开发指南:如何在 CentOS 7 上安装 Nginx Nginx 读作 engine x, 是一个免费的.开源的.高性能的 HTTP 和反向代理服务,主要负责负载一些访问量比较大的站点. ...
- python+pyqt5实现24点小游戏
本文实例为大家分享了python实现24点游戏的具体代码,供大家参考,具体内容如下 描述:一副牌中A.J.Q.K可以当成是1.11.12.13.任意抽取4张牌,用加.减.乘.除(可加括号)把牌面上的数 ...
- 第十一节:Web爬虫之数据存储(数据更新、删除、查询)
接着上一节的内容 5.MySQL数据更新 结果是将id=3的name进行更新操作,结果如下: 6.MySQL数据去重及更新 结果是判断数据是否有重复的,如果有重复的将不再存储,若没有重复的就更新数据进 ...
- 模拟select控件功能
直接上代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- PatentTips – Shader Interfaces
BACKGROUND Today's graphic processing units (GPUs) host all of the computations necessary to generat ...