75142913在线留言
GO语言学习笔记2:函数的定义与使用详解_Go语言_网络人

GO语言学习笔记2:函数的定义与使用详解

Kwok 发表于:2020-09-29 10:09:42 点击:9 评论: 0

GO语言是一个“面向函数”编程的语言,最少有一个main()函数,这也是程序的入口。

一、基本语法:

//基本语法
func 函数名字( 参数1 参数1类型,参数2 参数2类型,... ) [返回类型1,返回类型2] {
   函数体
}

//程序实例
func getSum(a int,b int) int{
    return a+b
}

返回值与参数不是必须的,只要没有return就不写返回参数。

func PrintHello() {
	fmt.Println("你好,世界!")
}
PrintHello()//使用无参数,无返回的函数

二、返回多个值:

//a,b int->a int,b int等同
func getSumAndSub(a,b int)(int,int){
    return a+b,a-b
}

var Sum,Sub=getSumAndSub(1,2) //这里Sum的值为3,Sub的值为-1
var Sum2,_=getSumAndSub(1,2) //这里Sum2的值为3,忽略第二个变量

三、递归函数:

func killNum(a int) {
	if a > 1 {
		a--
		killNum(a) //调用自己
	}
	fmt.Println(a)
}

说明:会调用自己并循环输出a每次减1的结果,直到不再满足IF条件。不写IF将成为一个死循环~

四、函数作为参数传给其它函数:

//定义一个将被作为参数调用的函数
func myFunc(a int) int {	
	return a+1
}
//定义一个将使用函数做为参数的函数
func useFunc(funcName func(int) int, num int) int {
	//funcName func(int) int作为一个函数参数1,格式需要写正确,即funcName是变量名 func(int传参类型) int返回类型。num 参数2
	return funcName(num)
}

//使用方法
fmt.Println(useFunc(myFunc, 1))
//或者用一个变量来接收返回的结果

res := useFunc(myFunc, 1) //res = 2

五、匿名函数

a := func(x,b int) int {
		return x + b
	}(10,1) //这里a的值等 11

匿名函数就是不用写函数名,即用即建,这里只能使用1次。

将变量变成一个函数来使用:

a := func(x,b int) int {
		return x + b
	}
fmt.Println(a(1,2)) //这里打印3

这里的a就可以反复使用了。

也可以将函数函数做为参数传给其它函数使用,以第四项为例:

//定义一个使用匿名函数做为参数的函数
func useFunc(funcName func(int) int, num int) int {
	return funcName(num)
}

//使用方法

a := useFunc(func(a int) int {
	return a + 1
}, 1)
fmt.Println(a)//将打印2

小提示:将匿名函数首字母大写的方式定义在main外就是一个全局匿名函数,将可以在整个程序中使用。

 六、init函数

init函数是一个做为初始化的函数,拥有比main更高的执行优先权,通常使用这个函数做为程序初始化用,并且在每个包里面都可以有一个init函数。

func init ( ) {
	fmt.Println("我将比main自动先执行,并不需要调用")
}
func main() {	
	fmt.Println("我是MAIN函数")
}

执行流程:全司变量定义(可以使用 var a=func()测试哦~) -> init函数->main函数

七、可变参数

可变参数支持0到多个参数,在参数不确定的情况下使用这个。这里的args实际是一个切片,使用args[n]访问到提交的参数。

func PrintArgs(a int, args ...int) {
	for i := 0; i < len(args); i++ {
		a += args[i]
	}
	fmt.Println("所有参数的和为:", a)
}
func main() {
	PrintArgs(1, 2, 3, 4, 5, 6)
}
//所有参数的和为: 21

args为通用写法但不是强制写法,可以使用其它名字代替。可变参数只能写到最后面,不能写到前面或者中间。

八、函数修改外部变量值

在大部分编程语言中,函数变量的作用域只在函数内,不能在函数外使用,GO语言中的函数是值拷贝,在函数内修改的变量,并不会改变外面变量的值,在PHP中只需要使用global关键字就可以实现修改函数内变量的值。

func sum(a int) {
	a = a + 1
}
func main() {
	a := 1
	sum(a) //这里并不能改变外部a的值
	fmt.Println(a)//依然打印1
}

但在程序开发中,我们有的时候需要通过函数修改外部变量的值,通常的做法为传一个指针参数进行修改。

func sum(a *int) {
	*a = *a + 10//*a代表指针指向的值
}
func main() {
	a := 1
	sum(&a)//&a为a内存地址
	fmt.Println(a)//因为直接修改了a的内存地址(&a)值(*a),所以打印出来11
}

实战使用:

func swap(x *int, y *int) {
	*x, *y = *y, *x //看不懂的请看 http://www.neter8.com/go/70.html 的第六条
}
func main() {
	var a int = 100
	var b int = 200
	fmt.Printf("交换前,a 的值 : %dn交换前,b 的值 : %d", a, b)
	fmt.Println()
	swap(&a, &b)
	fmt.Printf("交换后,a 的值 : %dn交换后,b 的值 : %d", a, b)
}

不使用指针的方法,效率没有指针高哦~

func sum(a int) int {
	return a + 10
}
func main() {
	a := 1
	a = sum(a)
	fmt.Println(a)
}

九、函数闭包

GO语言支持匿名函数作为一个结果返回假设声明的函数为父级(F),返回的匿名函数为子级(S),那么子级可以使用到父级里的变量,这样就形成了一个闭包。闭包可以理解成“定义在一个函数内部匿名函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

func sum(f int) func(int) int {
	val := 200
	return func(s int) int {
		return f + s + val //返回f+s+val的结果
	}
}
func main() {
	fun := sum(10) //这里是f的值
	res := fun(100)            //通过函数变量fun调用返回的匿名函数计算f+s+val的结果
	fmt.Println("res=", res) //输出为310,即:fun初始化提交过来的10+调用fun(100)的100+和函数内部的val300
}

通过上面的例子可以看到,匿名函数可以直接访问到上级函数传递过来的变量f和函数内部声明的变量val,即匿名函数与父级函数形成了一个变量的闭包。闭包的好处是初始化fun的时候参数只传1次,在调用的时候fun(200),可以任意变,适用于判断文件扩展名。在fun(文件名)就可以判断了,传统方式需要每次调用的时候传2个参数即:fun(".jpg","neter8.com.jpg")。

十、函数中的defer

这是一个延时执行函数,通常用于关闭文件、关闭数据库、关闭连接等,在函数执行完毕后再调用defer后面的语句,如果有多个defer的情况下GO语言是采用先进后出的机制(就像弹夹里放入子弹,先放进入的最后才发射)。

func OpenFile(filename string) {
	file = openfile(filename)
	defer file.close()//打包后可以马上关闭,为了防止忘记关闭的情况,也适用于数据库连接
	file.Write("写入或者其它操作执行,因为在函数完成以后才会关闭文件呢~")
}

再也不在为什么时候合适关闭资源而伤脑筋了~

十一、其它知识点:

1、函数有2种传递方式:

a.值传递,即:值拷贝。(如:int...、float...、string...、bool、数组、结构体struct,参考文章结尾的基本数据:http://www.neter8.com/go/70.html)

b.引用传递,即:内存地址的拷贝(如:指针、clice切片、map、管道chan、interface接口等)

一般来说地址拷贝效率要高很多。因为就一个内存地址,数据量会小。比如变量为一本书所有的内容情况下,要把值传给函数,则会在内存里再开辟一个同时大小的地址分配给函数里的局部变量使用,而引用传递只需要把内存地址传给函数即可,通过指针就能修改到外部变量的内容。

 

 

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:http://www.neter8.com/go/71.html
标签:函数GO
0
感谢打赏!

《GO语言学习笔记2:函数的定义与使用详解》的网友评论(0)

本站推荐阅读

热门点击文章