Go从入门到精通——使用函数
使用函数
本章介绍如下内容
- 函数是什么
- 定义不定参数函数
- 使用具名函数
- 使用递归函数
- 将函数作为值传递
函数是另一个核心要素,不仅仅是 Go 语言,在日常编程中亦是如此。
1.1 函数是什么?
简单地说,函数接受输入并返回输出。数据流经过函数时,将被变换。一个典型的示例是将两个数相加的简单函数,它接受两个数字,将它们相加并返回结果。
1 2 3 | func addUp(x int,y int) int{ return x + y } |
1.1.1 函数的结构
在 Go 语言中,函数向编译器和程序员提供了有关的信息,这些信息指出了函数将接受什么样的输入并提供什么样的输出。这种信息是在函数的第一行中提供的,而这一行被称为函数签名。我们再以函数 addUp 为例,阐述 Go 语言中函数的结构是什么样的。
1 2 3 | func addUp(x int,y int) int{ return x + y } |
关键字 func 指出这是一个函数的开头位置。接下来是函数名,这是可选的,但能够让您在其他地方调用(或使用)这个函数。接下来是一对括号,指出了函数接受什么样的值,在这里,是两个类型为 int 的值(带符号的整数,长度至少为 32 位)。在右括号后面是返回值,这里也是一个类型为 int 的值。左括号表示接下来为函数体,函数体以右括号结束。如果函数签名声明了返回值,则函数体必须以终止语句结束。通常有一个返回值,但并非总是如此。
1.1.2 返回单个值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package main import ( "fmt" ) func isEven(i int) bool { return i%2 == 0 } func main() { fmt.Printf( "%v\n" , isEven(1)) fmt.Printf( "%v\n" , isEven(2)) } |
要调用函数,可通过名称来对其进行引用,并提供所需的参数。调用了函数 isEven 两次,并将结果打印到终端。对函数调用次数没有任何限制。
1.1.3 返回多个值
在 Go 语言中,可在函数签名中声明多个返回值,让函数返回多个结果。在这种情况下,终止语句可返回多个值。在下面的例子中,函数签名指出函数不接受任何参数,并返回一个整数和一个字符串。在函数体中,return 语句返回了多个用逗号分隔的值。
func getPrize() (int, string) { i :=2 s := "goldfish" return i, s }
调用这个函数时,可直接将返回值赋给变量并使用它们。
func main(){ quantity, prize := getPrize() fmt.Printf("You won %v %v\n", quantity, prize) }
程序清单:演示了一个返回多个结果的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import "fmt" func getPrize() (int, string) { i := 2 s := "goldfish" return i, s } func main() { quantity, prize := getPrize() fmt.Printf( "You won %v %v\n" , quantity, prize) } |
1.2 定义不定参数函数
不定参数函数是参数数量不确定的函数。通俗地说,这意味着它们接受可变数量的参数。在 Go 语言中,能够传递可变数量的参数,但它们的类型必须与函数签名指定的类型相同。要指定不定参数,可使用 3 个点(...)。在下面的示例中,函数签名指定函数可接受任意数量的 int 参数。
1 2 | func sumNumbers(numbers...int) int{ } |
这个函数可接受一个或多个整数,您可使用它来计算任意多个整数的和并返回单个整数。在这个函数中,变量 numbers 是一个包含所有参数的切片。
1 2 3 4 5 6 7 | func sumNumbers(numbers...int) int { total := 0 for _, nmuber := range numbers { total += numbers } return total } |
您可使用这个函数来计算一系列整数的和。
1 2 3 4 | func main(){ result := sumNumbers(1,2,3,4) fmt.Printf( "The result is %v\n" ,result) } |
程序清单:使用了一个不定参数函数来将多个整数相加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package main import "fmt" func sumNumbers(numbers ...int) int { total := 0 for _, number := range numbers { total += number } return total } func main() { result := sumNumbers(1, 2, 3, 4) fmt.Printf( "The result is %v\n" , result) } |
1.3 使用具名返回值
具名返回值让函数能够在返回前将值赋给具名变量,这有助于提升函数的可读性,使其功能更加明确。要使用具名返回值,可在函数签名的返回值部分指定变量名。
1 | func sayHi()(x,y string){} |
这个签名指定将返回两个值,它们的类型都为 string;它还指定了变量名(x 和 y),可在函数体中给它们赋值。
1 2 3 4 5 | func sayHi() (x,y string){ x = "hello" y = "world" return } |
这个函数体中,在终止语句 return 前给具名变量进行了赋值。使用具名返回值时,无须显式地返回相应的变量。这被称为裸 return 语句。
1 2 3 | func main(){ fmt.Println(sayHi()) } |
调用这个函数时,将按声明顺序返回具名变量。
程序清单:具名返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import "fmt" func sayHi() (x, y string) { x = "hello" y = "World" return } func main() { fmt.Println(sayHi()) } |
1.4 使用递归函数
递归函数是不断调用自己直到满足特定条件的函数。要在函数中实现递归,可将调用自己的代码作为终止语句中的返回值。
程序清单:演示一个不断调用自己直到满足特定条件的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package main import "fmt" func feedMe(portion int, eaten int) int { eaten = portion + eaten if eaten >= 5 { fmt.Printf( "I'n full! I've eaten %d\n" , eaten) return eaten } fmt.Printf( "portion:%v,eaten: %v " , portion, eaten) fmt.Printf( "I'm still hungry! I've eaten %d\n" , eaten) return feedMe(portion, eaten) } func main() { feedMe(1, 0) } |
1.5 将函数作为值传递
Go 语言提供了一些函数式的编程功能,如能够将一个函数作为参数传递给其他函数。Go 将函数视为一种类型,因此可将函数赋给变量,以后再通过变量来调用它们。
1 2 3 4 5 | func main(){ fn := func () { fmt.Println( "function called" ) } } |
- 使用简短变量赋值运算符将一个函数赋给了变量 fn。
- 声明这个函数并将其定义为打印一行文本,让您知道它被调用了。
- 在变量名 fn 后使用 () 调用这个函数。
在 Go 语言中,函数是一种类型,因此可将其传递给其他函数。我们对前一个示例进行扩展,将变量 fn 传递给一个函数,并在这个函数中调用它。
程序清单:将函数作为参数传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package main import "fmt" func anotherFunction(f func () string) string { return f() } func main() { fn := func () string { return "function called" } fmt.Println(anotherFunction(fn)) } |
请注意,函数 anotherFunction 的签名中包含一个子函数签名,这表明这个参数是一个返回字符串的函数。接受函数依然需要声明其返回类型,它可以是任何类型,但这里也是字符串。
Go 语言中自定义函数要注意以下几点写法:
- 以关键字 func 开头自定义一个函数。
- 函数的名字与变量命名的要求基本一致。
- 函数后面的圆括号中定义了本函数接受的各个参数及其类型。
- 如果函数有返回值,在函数圆括号后应标明返回值的类型。
- 函数内部的所有代码应包含在一个花括号(大括号)中。
- 如果函数有返回值,必须至少有一条 return 语句来返回结果值,每一个 return 语句都是该函数代码执行的终点,意味着 return 语句返回结果值后将不再往下执行其他代码。
- 如果函数没有返回值,也可以用不带返回值的 return 语句来返回(强制终止函数的运行)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具