Go语言之函数

函数

定义

func 函数名(传参类型) 返回值类型{}

func main() {
	r := sum(1,2);
	fmt.Println(r)  // 3
	test();  // aaa
	m,n := text();
	fmt.Println(m,n)  //1 aa
}

// 返回数值类型
func sum(x int,y int) int{
	return x + y;
}

// 没有返回值
func test(){
	fmt.Println("aaa")
}

// 返回值可以命名变量,相当于在函数内声明了变量。
func sum(x int,y int) (res int){
	res = x + y;
	return   // 返回值命名过的话可以直接return
}

// 多个返回值
func text() (int,string){
	return 1,"aa"
}

// 当参数连续多个类型一致时,可以简写参数类型
func text1(x,y,z int,a,s,d string) {
	...
}


// 可变长参数
// 可变长参数必须放在函数参数的最后
func main() {
	f1("aaa",1,2,3,4,5)  // aaa [1 2 3 4 5]
}
func f1(x string,y ...int){
	fmt.Println(x)
	fmt.Println(y)  // y 的类型为切片
}

defer

定义defer的语句将会在函数将要执行return时在进行操作

正常情况下

func main() {
	test();  // 1 2 3
}

func test(){
	fmt.Println(1);
	fmt.Println(2);
	fmt.Println(3);
}

使用defer

func main() {
	test();  // 1 3 2
}

func test(){
	fmt.Println(1);
	defer fmt.Println(2);
	fmt.Println(3);
}

defer的使用场景通常在关闭链接的时候使用,比如链接数据库,读取文件等等。
当多个defer同时出现时,遵循先进后出原则。

func main() {
	test();  // 1 5 4 3 2
}

func test(){
	fmt.Println(1);
	defer fmt.Println(2);
	defer fmt.Println(3);
	defer fmt.Println(4);
	fmt.Println(5);
}

defer运行时机
Go语言的函数中return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值之后,RET指令之前。
在这里插入图片描述

在这里插入图片描述
小案例:

func main() {
	fmt.Println(test());  // 5
}

func test() int{
	x := 5;
	defer func(){
		x++
	}();
	return x;
}

匿名函数和闭包

匿名函数一般用在函数内部,是个没有名字的函数

x1 := func (x, y int){
	fmt.Println(x + y);
}
x1(1,2);  // 3

看到这或许会有疑问,这样写的话为什么不直接定义一个带名字的函数?
这是因为函数内是不可以定义有名字的函数,同时匿名函数若是只调用一次的话,可以定义为立即执行函数。(你没看错,和js的语法一致)

func (){
	fmt.Println(1111)
}();

闭包的作用是在于使让内部函数使用外部变量。

func main() {
	a := test(1);
	a();  // 2
	a();  // 3
}

func test(x int) func() {
	return func (){
		x++;
		fmt.Println(x);
	};
}

内置函数

目前Go语言中没有异常机制,但是使用panic / recover模式来处理错误。panic可以在任何场景下引发,recover只有在defer调用的函数中有效。举个例子:

func main() {
	a();
	b();
	c();
}

func a(){
	fmt.Println("1");
}
func b(){
	panic("报错啦")
}
func c(){
	fmt.Println("3");
}

输出:
在这里插入图片描述
在程序运行期间,b函数运行出错,抛出错误并退出程序执行。这个时候可以使用recover来恢复现场并且获取报错信息。


func main() {
	a();
	b();
	c();
}

func a(){
	fmt.Println("1");
}
func b(){
	defer func(){
		err := recover();
		fmt.Println("释放数据库连接。。。")
		fmt.Println(err)
	}();
	panic("报错啦")
}
func c(){
	fmt.Println("3");
}

输出:
在这里插入图片描述
可以看到程序不会因为报错而停止运行,而是继续执行c函数。
注意事项:

  1. recover必须搭配defer使用
  2. defer一定要在可能引发panic语句之前定义,否则将会永远运行不到。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值