函数

函数的声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

//函数返回一个无名变量,返回值列表的括号省略
func add(a, b int) int {
return a + b
}

func main() {
sum := add(1, 23)
fmt.Println(sum)
}

可变参数

多个类型一致的参数

在参数类型前面加 ... 表示一个切片,用来接收调用者传入的参数。注意,如果该函数下有其他类型的参数,这些其他参数必须放在参数列表的前面,切片必须放在最后。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func show(args ...string) int {
sum := 0
for _, item := range args {
fmt.Println(item)
sum += 1
}
return sum
}

func main() {
fmt.Println(show("111","222","333"))
}

多个类型不一致的参数

如果传多个参数的类型都不一样,可以指定类型为 ...interface{} ,然后再遍历。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func show(args ...interface{}) int {
sum := 0
for _, a := range args {
fmt.Println(a)
sum++
}
return sum
}

func main() {
fmt.Println(show("jpc", 21))
}

解序列

使用 ... 可以用来解序列,能将函数的可变参数(即切片)一个一个取出来,传递给另一个可变参数的函数,而不是传递可变参数变量本身。

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
var s []string
s = append(s, []string{"111", "222", "333"}...)
fmt.Println(s)
}

函数的返回值

当函数没有返回值时,函数体可以使用 return 语句返回。在 Go 中一个函数可以返回多个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"errors"
"fmt"
)

func show(name string, age int) (string, error) {
if name == "" {
return "", errors.New("名字不能为空")
}
return name, nil
}

func main() {
name, err := show("jpc", 21)
fmt.Println(name, err)
}

匿名函数

没有名字的函数就叫 匿名函数 ,它只有函数逻辑体,而没有函数名。匿名函数只拥有短暂的生命,一般都是定义后立即使用。

内部方法与外部方法

在 Go 语言中,函数名通过首字母大小写实现控制对方法的访问权限。

  • 当方法的首字母为 大写 时,这个方法对于 所有包 都是 Public ,其他包可以随意调用。
  • 当方法的首字母为 小写 时,这个方法是 Private ,其他包是无法访问的。

头等函数

把函数赋值给变量

Go 语言拥有 头等函数(First-class Function) ,头等函数是指函数可以被当作变量一样使用,即函数可以被当作参数传递给其他函数,可以作为另一个函数的返回值,还可以被赋值给一个变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import "fmt"

func main() {
bookFunc := func() {
fmt.Println("这是一个函数")
}
bookFunc()
fmt.Printf("bookFunc 的类型是 %T\n", bookFunc)
}

// 输出
/*
《Go语言极简一本通》
bookFunc 的类型是 func()
*/

传递一个函数作为参数

我们把 接收一个或多个函数作为参数 或者 返回值也是一个函数 的函数称为 高阶函数(Hiher-order Function)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

func Out(show func(name, hobby string) string) {
fmt.Println(show("jpc", "羽毛球"))
}

func main() {
f := func(x, y string) string {
return x + y
}
Out(f)
}

返回一个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

// show返回一个函数
func show() func(name, hobby string) string {
return func(x, y string) string {
return x + y
}
}

func main() {
f := show()
fmt.Println(f("jpc", "羽毛球"))
}
// 输出 jpc羽毛球

闭包

闭包(Closure) 是匿名函数的一个特例。当一个匿名函数所访问的变量定义在函数体的外部时,就称这样的匿名函数为闭包。

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
x := 1000
func() {
fmt.Println(x)
}()

}