Go 语言函数
函数是基本的代码块,用于执行一个任务。
Go 语言最少有个 main() 函数。
你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。
函数声明告诉了编译器函数的名称,返回类型,和参数。
Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数字,则返回数组中包含的函数个数。
在前面的部分其实我们已经用到了函数编程。这里提几点Go语言函数的特殊点
1、多返回值
func eval(a,b int,op string) (int,error){
//每一个case自带break,如果不需要break要加上fallthrough(人性化)
switch op {
case "+":
return a+b,nil
case "-":
return a-b,nil
case "*":
return a*b,nil
case "/":
q,_ := div(a,b)//只接收一个返回值
return q,nil
default:
//panic报错,中断程序的执行
//panic("unsupported operator"+op)
return 0,fmt.Errorf("unsupported operator:%s",op)
}
}
在我们之前做这部分时,如果程序报错。我们采用的是panic方法,返回错误信息,并且中断程序运行。但是go语言提供了强大的错误机制error,可以 在不中断程序的情况下给出错误信息。当然这也是多返回值的主要用途之一。
多返回值仅接收部分返回值。
比如说,我们定义一个除余函数,同时返回除数和余数。
func div(a,b int)(q,r int){//仅用于简单函数,对于调用者而言没有区别
return a/b,a%b
}
我们在另一个函数中调用,只想得到除数结果怎们办呢?go语言采用下划线“_”来接收不想使用的返回值。
q,_ := div(a,b)//只接收一个返回值
返回值指定名称
我们在上面那个div函数中发现,我们可以给返回值指定名称.并且在调用时,可以使用编辑器自动补全函数返回值名称(jetbrains中快捷键为:ctrl+alt+v)当然,在较为简短的函数中可以这样用,但是一旦函数体过长,则会导致赋值比较混乱,使得代码可阅读性变差。
2、函数式编程
函数式编程以后还会用到,并详细说明。这里先大体了解一下Go语言的函数式编程。
//函数式编程。函数的参数也可以是函数
func apply(op func(int,int) int,a,b int) int {
p := reflect.ValueOf(op).Pointer()
opname := runtime.FuncForPC(p).Name()
fmt.Printf("calling function %s with %d %d",opname,a,b)
return op(a,b)
}
在上述函数中。我们看到,函数的参数也可以是一个函数。这样使得代码的分块更加明显
其中通过反射机制获得函数名不用太在意。学过java应该对反射不陌生。以后详细讲,有个印象就好。
一方面我们可以外部定义函数
func pow(a,b int) int{
return int(math.Pow(float64(a),float64(b)))
}
//main函数中调用
fmt.Println(apply(pow,3,4))
另一方面,较为简短的实现函数我们直接可以在函数调用中直接定义
fmt.Println(apply(
func(a int, b int) int {
return int(math.Pow(
float64(a), float64(b)))
},3,4))
这里运行结果是
我们可以看到这里通过反射拿到的函数名为 main这个包下main函数中的匿名函数func1.由于我们没有指定函数名。go语言给我们自动分配了一个这样的名字。
3、可变参数列表
在go语言中虽然省掉了一些默认参数之类的定义,但是保留了可变参数列表。使用方法类似数组
func sum(numers ...int) int {
sum := 0
for i:=range numers{
sum+=numers[i]
}
return sum
}
fmt.Println(sum(1,2,3,4,5))
这样就能得出15,使用方法类似于数组。