Go语言函数

一、基本介绍

为完成某一功能的程序语句的集合,称为函数,分为自定义函数和系统函数。

二、基本语法

func 函数名 (形参列表) (返回值类型列表) {
	执行语法...
	return 返回值列表
}

例子:

// 函数返回两个数的最大值
func max(num1 int, num2 int) int {
	var result int
	if num1 > num2 {
		result = num1
	} else {
		result = num2
	}
	return result
}

三、函数的调用

package main

import (
	"fmt"
)

func main() {
	var num1 int = 300
	var num2 int = 200
	var result int
	// 调用函数并返回最大值
	result = max(num1, num2)
	fmt.Printf("最大值为%d\n", result)
}

// 函数返回两个数的最大值
func max(num1 int, num2 int) int {
	var result int
	if num1 > num2 {
		result = num1
	} else {
		result = num2
	}
	return result
}

输出结果:

最大值为300

四、函数的调用机制

通过一个例子来分析:编写一个函数传入一个值,并将值加一

package main

import "fmt"

func main() {
	var a int = 10
	test(a)
	fmt.Println("main() a=",a)
}

func test (a int) {
	a += 1
	fmt.Println("test() a =",a)
}

输出结果:

test() a = 11
main() a= 10

示意图如下:

image

说明

  1. 在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身处理让这个空间和其他的栈空间区分开来
  2. 在每个函数对应的栈中,数据空间是独立的,不会混淆
  3. 当一个函数调用完毕(执行完毕)后,程序会销毁这个函数对应的栈空间

五、函数参数的传递方式

  1. 值传递(值类型:基本数据类型int系列,float系列,bool,string,数组,结构体struc)
  2. 引用传递(引用类型:指针,切片slice,map,interface,管道chan等都是引用类型)

其实不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说地址拷贝效率高,因为数据量小,而值拷贝取决于拷贝数据的大小,数据越大,效率越低、

六、函数返回多个值

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

package main

import (
	"fmt"
)

func main() {
	var a string = "帅"
	var b string = "哥"
	fmt.Printf("交换前a,b:%v%v\n", a, b)
	a, b = swap(a, b)
	fmt.Printf("交换后a,b:%v%v\n", a, b)
}
// 函数交换值
func swap(str1 string, str2 string) (string, string) {
	return str2, str1
}

输出结果:

交换前a,b:帅哥
交换后a,b:哥帅

七、递归调用

例子:使用递归调用的方式,求出前10个斐波那契数1,1,2,3,5,8,13...

package main

import (
	"fmt"
)

func main() {
	for i := 1; i <= 10; i++ {
		res := fbn(i)
		fmt.Printf("%d ", res)
	}
}

func fbn(n int) int {
	if n == 1 || n == 2 {
		return 1
	} else {
		return fbn(n-1) + fbn(n-2)
	}
}

输出结果:

1 1 2 3 5 8 13 21 34 55
八、注意细节
  1. 函数的形参列表可以是多个,返回值列表也可以是多个
  2. 形参列表和返回值列表的数据类型可以是值类型和引用类型
  3. 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其他包文件使用,类似public,首字母小写,只能被本包文件使用,其他包文件不能使用,类似private
  4. 函数中的变量时局部的,函数外不生效。
  5. 基本类型和数组默认都是值传递,即进行值拷贝,在函数内修改,不会影响到原来的值。
  6. 如果希望函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量,从效果上类似引用。
  7. go函数不支持重载
  8. 在Go中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型变量了。通过该变量可以对函数调用。
  9. 函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用。
  10. 为了简化数据类型定义,Go支持自定义数据类型
    基本语法:
type 自定义数据类型名 数据类型 //相当于起了一个别名

例如:

type myfunc func(int,int) int
  1. 支持函数返回值命名
    例如:
func cal(a int, b int) (sum int, sub int) {
	sum = a + b
	sub = a - b
	return
}
  1. 如果返回多个值时,在接受时,希望忽略某个返回值,则使用 _ 符号表示占位忽略。
  2. Go支持可变参数
package main

import (
	"fmt"
)

func main() {
	res := sum(10, 20, 30)
	fmt.Printf("res=%d\n", res)
}

func sum(a int, args ...int) int {
	sum := a
	for i := 0; i < len(args); i++ {
		sum += args[i]
	}
	return sum
}

输出结果:

res=60

说明:

  • args是slice,通过args[index]可以访问各个值。
  • 如果一个函数的形参列表中有可变参数,则可变参数需要放在形参最后。
  1. 如果返回一个值时,返回值类型列表,可以不写()。
posted @ 2021-05-09 12:56  若雨蚂蚱  阅读(79)  评论(0编辑  收藏  举报