05函数、异常

函数

创建

首先,需要清楚一个函数由哪几部分构成。分别为函数标记func关键字,函数名,函数形参,返回类型,函数体。注意函数中不能定义有名函数*(可以定义匿名函数)*。例如:

func add(a,b int) int{//定义全局函数
	return a+b
}
func main() {
	fmt.Println(add(4,5))//调用全局函数

	func(a,b int){//执行只能执行一次的匿名函数。func()括号内为形参,{}为函数体,最后的括号内为实参
		fmt.Println(a+b)
	}(1,3)

	temp:= func(a,b int) int{//可以将该匿名函数赋值给一个变量
		return a+b
	}
	fmt.Println(temp(3,5))
}

函数和返回值

变长参数

参数参数可以是定长的,也可以是变长的。变长参数使用...表示。例如:

func add(arr... int) int{
	sum:=0
	for i:=range arr{//迭代遍历形参arr
		sum+=arr[i]
	}
	return sum
}
/*
调用时可以arr()什么都不传递
也可以arr(0,1,5,2)传递多个参数
*/

go也可以进行地址传参,也可以将数组作为参数传递。可以返回0个,一个或多个值。当然也可以将函数作为参数进行传递,或是返回一个函数。

返回多值

返回多个值时,返回值的类型需要用括号括起来:

func list() (int,int){//用括号括起来
	return 0,1//逗号隔开
}
func main() {
	a,b:=list()//必须用两个参数接收
	fmt.Println(a,b)
}

传址

go像函数传递地址的写法和c++一样:

func swap(a,b *int){//接收两个int类型的指针
	*b,*a=*a,*b
}
func main() {
	a:=1
	b:=2
	swap(&a,&b)//传递两个int类型的地址
	fmt.Println(a,b)
}

切片作为参数或返回值

将切片作为函数的参数时,实际上就是地址传值。在函数体内更改切片会影响到切片值。

切片作为形参:

func add1(a []int){
	for i:=range a{
		a[i]+=1//会影响到实参的值
	}
}
func main() {
	b:=make([]int,3)
	b[0],b[1],b[2]=1,2,3
	add1(b)//实际上是传递了b的地址
	fmt.Println(b)//此时的b已经被改变了
}
/*
输出:
[2 3 4]
*/

返回切片:

func add1(n int)[]int{
	a:=make([]int,n)
	return a
}
func main() {
	b:=add1(8)//将返回一个初始长度为8的int类型的切片
	fmt.Println(b)
}

应用函数闭包

例如要给一些字符串加上不同的后缀。则可以应用函数闭包去实现:

func app(a string)func(pre string)string{//传入一个字符串后缀
	return func(pre string)string{//返回一个匿名函数
		return pre+a//匿名函数返回参数和后缀的组合
	}
}
func main() {
	addJpg :=app(".jpg")
	fmt.Println(addJpg("001"))
	fmt.Println(addJpg("002"))
	addPng :=app(".png")
	fmt.Println(addPng("001"))
	fmt.Println(addPng("002"))
}
/*
输出:
001.jpg
002.jpg
001.png
002.png
*/

异常

defer语句

defer语句用于执行程序结束后的一些事情。当有多个defer语句时,遵循“先进后出”原则。例如:

defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
/*输出:
3
2
1
*/

故障恢复

defer用于处理程序执行后的一些事情。当程序非正常结束时,也是要执行defer的。recover()函数用于接受一个错误。

defer func() {
    err:=recover()//用于接收错误
    if err!=nil{
        fmt.Println("出错了:",err)
    }else{
        fmt.Println("无错误")
    }
}()
var a,b int=1,0
a=a/b//  1/0
/*
输出:
出错了: runtime error: integer divide by zero
*/
l{
        fmt.Println("出错了:",err)
    }else{
        fmt.Println("无错误")
    }
}()
var a,b int=1,0
a=a/b//  1/0
/*
输出:
出错了: runtime error: integer divide by zero
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值