多返回值
一个函数能够返回不止一个结果。
golang的垃圾回收机制将回收未使用的内存,但不能指望它会释放未使用的操作系统资源,比如打开的文件以及网络连接。必须显示地关闭它们。- 返回一个多值结果可以是调用另一个多值返回的函数。
- 一个函数如果有命名的返回值,可以省略
return语句的操作数,这称为裸返回。
错误
error是内置的接口类型。- 一般当一个函数返回一个非空错误时,它其他的结果都是未定义的而且应该忽略。
- 与许多其他语言不同,
golang通过使用普通的值而非异常来报告错误。
错误处理策略
- 调用
log.Fatalf就和所有的日志函数一样,它默认会将时间和日期作为前缀添加到错误消息前。 - 如果检测到的失败导致函数返回,成功的逻辑一般不会放在
else块中而是在外层的作用域中。
文件结束标识
io包保证任何由文件结束引起的读取错误,始终都将会得到一个相同的错误------io.EOF。
函数变量
就像其他值,函数变量也有类型,而且它们可以赋给变量或者传递或者从其他函数中返回。
func square(n int) int { return n * n }
f := square
strings.Map对字符串中的每一个字符使用一个函数,将结果连接起来变成另一个字符串。
func add1(r rune) rune { return r + 1 }
fmt.Println(strings.Map(add1, "VMS")) // "WNT"
匿名函数
函数字面量就像函数声明,但在func关键字后面没有函数的名称。它是一个表达式,它的值称作匿名函数。
func add1(r rune) rune { return r + 1 }
fmt.Println(strings.Map(add1, "VMS")) // "WNT"
// 等价于
fmt.Println(strings.Map(func(r rune) rune { return r + 1 }, "VMS"))
- 以这种方式定义的函数能够获取整个词法环境。
func squares() func() int {
var x int
return func() int {
x ++
return x * x
}
}
func main() {
f := squares()
fmt.Println(f()) // "1"
fmt.Println(f()) // "4"
fmt.Println(f()) // "9"
}
这次的变量生命周期也不是由它的作用域所决定的:变量x在main函数中返回squares函数后依旧存在(虽然x在这个时候是隐藏在函数变量f中的)。
- 函数变量类似于使用闭包方法实现的变量,
golang程序员通常把函数变量成为闭包。