课程表

Go语言课程

工具箱
速查手册

Go 语言函数

当前位置:免费教程 » 程序设计 » Go语言

函数是基本的代码块,用于执行一个任务。

Go 语言最少有个 main() 函数。

你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。

函数声明告诉了编译器函数的名称,返回类型,和参数。

Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数字,则返回数组中包含的函数个数。


函数定义

Go 语言函数定义格式如下:

  1. func function_name( [parameter list] ) [return_types] {
  2. 函数体
  3. }

函数定义解析:

  • func:函数由 func 开始声明
  • function_name:函数名称,函数名和参数列表一起构成了函数签名。
  • parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
  • 函数体:函数定义的代码集合。

实例

以下实例为 max() 函数的代码,该函数传入两个整型参数 num1 和 num2,并返回这两个参数的最大值:

  1. /* 函数返回两个数的最大值 */
  2. func max(num1, num2 int) int {
  3. /* 声明局部变量 */
  4. var result int
  5.  
  6. if (num1 > num2) {
  7. result = num1
  8. } else {
  9. result = num2
  10. }
  11. return result
  12. }

函数调用

当创建函数时,你定义了函数需要做什么,通过调用改函数来执行指定任务。

调用函数,向函数传递参数,并返回值,例如:

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. /* 定义局部变量 */
  7. var a int = 100
  8. var b int = 200
  9. var ret int
  10.  
  11. /* 调用函数并返回最大值 */
  12. ret = max(a, b)
  13.  
  14. fmt.Printf( "最大值是 : %d\n", ret )
  15. }
  16.  
  17. /* 函数返回两个数的最大值 */
  18. func max(num1, num2 int) int {
  19. /* 定义局部变量 */
  20. var result int
  21.  
  22. if (num1 > num2) {
  23. result = num1
  24. } else {
  25. result = num2
  26. }
  27. return result
  28. }

在线运行实例

以上实例在 main() 函数中调用 max()函数,执行结果为:

  1. 最大值是 : 200

函数返回多个值

Go 函数可以返回多个值,例如:

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func swap(x, y string) (string, string) {
  6. return y, x
  7. }
  8.  
  9. func main() {
  10. a, b := swap("Mahesh", "Kumar")
  11. fmt.Println(a, b)
  12. }

在线运行实例

以上实例执行结果为:

  1. Kumar Mahesh

函数参数

函数如果使用参数,该变量可称为函数的形参。

形参就像定义在函数体内的局部变量。

调用函数,可以通过两种方式来传递参数:

传递类型 描述
值传递 值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递 引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数。


函数用法

函数用法 描述
函数作为值 函数定义后可作为值来使用
闭包 闭包是匿名函数,可在动态编程中使用
方法 方法就是一个包含了接受者的函数

函数值传递

传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数。

以下定义了 swap() 函数:

  1. /* 定义相互交换值的函数 */
  2. func swap(x, y int) int {
  3. var temp int
  4.  
  5. temp = x /* 保存 x 的值 */
  6. x = y /* 将 y 值赋给 x */
  7. y = temp /* 将 temp 值赋给 y*/
  8.  
  9. return temp;
  10. }

接下来,让我们使用值传递来调用 swap() 函数:

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. /* 定义局部变量 */
  7. var a int = 100
  8. var b int = 200
  9.  
  10. fmt.Printf("交换前 a 的值为 : %d\n", a )
  11. fmt.Printf("交换前 b 的值为 : %d\n", b )
  12.  
  13. /* 通过调用函数来交换值 */
  14. swap(a, b)
  15.  
  16. fmt.Printf("交换后 a 的值 : %d\n", a )
  17. fmt.Printf("交换后 b 的值 : %d\n", b )
  18. }
  19.  
  20. /* 定义相互交换值的函数 */
  21. func swap(x, y int) int {
  22. var temp int
  23.  
  24. temp = x /* 保存 x 的值 */
  25. x = y /* 将 y 值赋给 x */
  26. y = temp /* 将 temp 值赋给 y*/
  27.  
  28. return temp;
  29. }

在线运行实例

以上代码执行结果为:

  1. 交换前 a 的值为 : 100
  2. 交换前 b 的值为 : 200
  3. 交换后 a 的值 : 100
  4. 交换后 b 的值 : 200

函数引用传递

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

引用传递指针参数传递到函数内,以下是交换函数 swap() 使用了引用传递:

  1. /* 定义交换值函数*/
  2. func swap(x *int, y *int) {
  3. var temp int
  4. temp = *x /* 保持 x 地址上的值 */
  5. *x = *y /* 将 y 值赋给 x */
  6. *y = temp /* 将 temp 值赋给 y */
  7. }

以下我们通过使用引用传递来调用 swap() 函数:

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. /* 定义局部变量 */
  7. var a int = 100
  8. var b int= 200
  9.  
  10. fmt.Printf("交换前,a 的值 : %d\n", a )
  11. fmt.Printf("交换前,b 的值 : %d\n", b )
  12.  
  13. /* 调用 swap() 函数
  14. * &a 指向 a 指针,a 变量的地址
  15. * &b 指向 b 指针,b 变量的地址
  16. */
  17. swap(&a, &b)
  18.  
  19. fmt.Printf("交换后,a 的值 : %d\n", a )
  20. fmt.Printf("交换后,b 的值 : %d\n", b )
  21. }
  22.  
  23. func swap(x *int, y *int) {
  24. var temp int
  25. temp = *x /* 保存 x 地址上的值 */
  26. *x = *y /* 将 y 值赋给 x */
  27. *y = temp /* 将 temp 值赋给 y */
  28. }

在线运行实例

以上代码执行结果为:

  1. 交换前,a 的值 : 100
  2. 交换前,b 的值 : 200
  3. 交换后,a 的值 : 200
  4. 交换后,b 的值 : 100

函数作为值

Go 语言可以很灵活的创建函数,并作为值使用。以下实例中我们在定义的函数中初始化一个变量,该函数仅仅是为了使用内置函数 math.sqrt() ,实例为:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "math"
  6. )
  7.  
  8. func main(){
  9. /* 声明函数变量 */
  10. getSquareRoot := func(x float64) float64 {
  11. return math.Sqrt(x)
  12. }
  13.  
  14. /* 使用函数 */
  15. fmt.Println(getSquareRoot(9))
  16.  
  17. }

在线运行实例

以上代码执行结果为:

  1. 3

函数闭包

Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。

以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包中递增 i 变量,代码如下:

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func getSequence() func() int {
  6. i:=0
  7. return func() int {
  8. i+=1
  9. return i
  10. }
  11. }
  12.  
  13. func main(){
  14. /* nextNumber 为一个函数,函数 i 为 0 */
  15. nextNumber := getSequence()
  16.  
  17. /* 调用 nextNumber 函数,i 变量自增 1 并返回 */
  18. fmt.Println(nextNumber())
  19. fmt.Println(nextNumber())
  20. fmt.Println(nextNumber())
  21. /* 创建新的函数 nextNumber1,并查看结果 */
  22. nextNumber1 := getSequence()
  23. fmt.Println(nextNumber1())
  24. fmt.Println(nextNumber1())
  25. }

在线运行实例

以上代码执行结果为:

  1. 1
  2. 2
  3. 3
  4. 1
  5. 2

函数方法

Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。语法格式如下:

  1. func (variable_name variable_data_type) function_name() [return_type]{
  2. /* 函数体*/
  3. }

下面定义一个结构体类型和该类型的一个方法:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. /* 定义函数 */
  8. type Circle struct {
  9. radius float64
  10. }
  11.  
  12. func main() {
  13. var c1 Circle
  14. c1.radius = 10.00
  15. fmt.Println("Area of Circle(c1) = ", c1.getArea())
  16. }
  17.  
  18. //该 method 属于 Circle 类型对象中的方法
  19. func (c Circle) getArea() float64 {
  20. //c.radius 即为 Circle 类型对象中的属性
  21. return 3.14 * c.radius * c.radius
  22. }

在线运行实例

以上代码执行结果为:

  1. Area of Circle(c1) = 314
转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号