golang学习笔记4 | 青训营

62 阅读2分钟

多返回值

一个函数能够返回不止一个结果。

  • 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"
}

这次的变量生命周期也不是由它的作用域所决定的:变量xmain函数中返回squares函数后依旧存在(虽然x在这个时候是隐藏在函数变量f中的)。

  • 函数变量类似于使用闭包方法实现的变量,golang程序员通常把函数变量成为闭包。