函数在任何语言里都是非常重要的角色,特别是 go 或 js ,函数作为一等公民的存在,我们必须把它嚼烂。
func name(参数列表) (返回值列表) {
函数体
}
go 的函数以 func
声明,我感觉除了多了参数类型和返回值类型,其他都跟 js 差不多,因为 go 也有匿名函数,也可以把函数赋值给其他变量,非常方便。
func add(x int, y int) int {return x + y}
func add(x, y int) int {return x + y}
如果参数类型一致,可以合并声明。
感觉都差不多,略。。
这是我第一次接触函数返回多值的情况,非常有意思。
func test(a, b int) (int, int) {
a++
b++
return a, b
}
一般 go 会在第二个参数当做错误值返回。
这里主要就是第二个参数的应用,系统里N多包都会返回两个参数,第二个是错误参数,方便判断。
resp, err := http.Get(url)
if err != nil{
return nill, err
}
在Go中,函数被看作第一类值(first-class values), 用 js 的术语来说,就是函数表达式。
test := func(a, b int) (int, int) {
a++
b++
return a, b
}
跟 js 不一样的是,当直接赋值时,函数名不能写。
而定义函数类型的变量时,写法需要注意,而且函数类型变量的零值是 nil
。
var f func(int) int
感觉把 js 函数概念拆开来了。。
这里的匿名函数,就是一个没有函数名的 函数字面量 ,这里就不多记录了,反正 jser 都懂的。
在参数名后面加 ...
可以把多余参数当做数组保存在这个变量中。
跟 es6 的特性差不多,不过 es6 的是在参数名前。
func sum(vals...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
调用的时候可以传入多参或者通过切片类型解构调用。
values := []int{1, 2, 3, 4}
fmt.Println(sum(1, 2, 3, 4)) // "10"
fmt.Println(sum(values...)) // "10"
通过在某个语句前加 defer
关键字,让该语句在函数 return
后执行。
多语句的情况下可以提供匿名函数处理。
func Parse(input string) (s *Syntax, err error) {
defer func() {
if p := recover(); p != nil {
err = fmt.Errorf("internal error: %v", p)
}
}()
// ...parser...
}
目前我的理解只是通过 defer
加 recover
来处理函数内部运行时的异常。
函数部分整体来说跟 es6 有着不少类似之处,语法层面的理解还是比较容易的。更深层次的理解,需要在之后实际应用中体会了。