package main
import (
"fmt"
"math"
"reflect"
"runtime"
)
/**
返回值类型写在最后面
可以返回多个值,函数返回多个值时可以起名字,仅用于非常简单的函数,对于调用者只是提示作用
函数作为参数
没有默认参数,可选参数
*/
//函数 返回err就可以不用panic中断执行
func eval2(a,b int,op string) (r int,e error) {
switch op {
case "+":
return a + b,nil
case "-":
return a - b,nil
case "*":
return a * b,nil
case "/":
return a / b,nil
default:
return 0,fmt.Errorf("unsupported operation: %s",op)
}
}
//函数可以返回多个值,可以给返回值取名字,取值时可以"_"跳过某一个值 13 / 4 = 3....1
func div(a,b int)(q,r int) {
return a/b,a%b
}
/*
函数式编程
函数的参数,函数的返回值,函数体内都可以有函数
复合函数
*/
func apply(opfunc(int, int) int,a,b int) int {
//取到op方法名字,reflect包可以进行反射
p := reflect.ValueOf(op).Pointer()//获得函数指针
opName := runtime.FuncForPC(p).Name()//通过runtime获得函数名
fmt.Printf("calling function %s with args" +"(%d,%d)",opName,a,b)
return op(a,b)
}
//定义pow函数
func pow(a,b int) int{
return int(math.Pow(float64(a),float64(b)))
}
//可变参数列表,“...”表示随便传多少参数
func sun(numbers ...int) int {
s :=0
for i :=range numbers {
s += numbers[i]
}
return s
}
/**指针
指针不能运算
*参数传递
值传递:拷贝一份到函数里面
引用传递:没拷贝到函数里面,会改变
*go语言只有值传递一种方式
*/
/**数组
*/
func main() {
//
fmt.Println(eval2(8,7,"*"))
//
if r,e := eval2(5,6,"x");e != nil {
fmt.Printf("error: %s\n",e)
}else {
fmt.Println(r)
}
//
q,r := div(13,4)
fmt.Println(q,r)
//只取第一个值
a,_ := div(8,3)
fmt.Println(a)
//显式声明函数
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))
//可变列表
fmt.Println(sun(1,2,3,4,5,6,7,8,9))
}