函数"/>
Go学习:函数
单个返回值
func main() {fmt.Println(eval(2,3,"*"))
}
func eval(a int, b int, op string) int {switch op {case "+":return a + bcase "-":return a - bcase "*":return a * bcase "/":return a/bdefault:panic("unsupported operation:" + op)}
}
// 执行输出6
两个返回值
不定义返回值的属性名
func main() {fmt.Println(div(10, 3))
}
func div(a, b int) (int, int) {return a / b, a % b
}
// 求商和余数;输出3和1
定义返回值的属性名
func main() {q, r := div(10, 3)fmt.Println(q, r)
}
func div(a, b int) (q,r int) {q = a / br = a % breturn
}
一般go函数定义两个返回值都是返回一个值和一个error;定义返回值属性名是为了调用的时候可以自动的使用函数的返回值,但是这种返回值只有在函数代码比较少的时候才适用;代码太多不好看到在哪里给返回值进行赋值了;
返回一个数值一个错误
- 第一段代码如果我们op不传加减乘除符号就会报错,中断程序的执行;把eval函数改成两个返回值,一个int一个error,程序就不会在因为报错中断执行了,如果发生错误就会将error返回;
func main() {if res, err := eval(4, 4, "/");err != nil{fmt.Println("Error:",err)}else {fmt.Println(res)}if res, err := eval(3, 4, "--");err != nil{fmt.Println("Error:",err)}else {fmt.Println(res)}
}
func eval(a int, b int, op string) (int, error) {switch op {case "+":return a + b, nilcase "-":return a - b, nilcase "*":return a * b, nilcase "/":return a / b, nildefault://panic("unsupported operation:" + op)return 0, fmt.Errorf("unsupported operation: %s", op)}
}
// 一个返回正确数值;一个返回错误
// 1
// Error: unsupported operation: --
两个返回值只使用一个
func main() {if res, err := eval(4, 4, "/");err != nil{fmt.Println("Error:",err)}else {fmt.Println(res)}if res, err := eval(3, 4, "--");err != nil{fmt.Println("Error:",err)}else {fmt.Println(res)}
}
func eval(a int, b int, op string) (int, error) {switch op {case "+":return a + b, nilcase "-":return a - b, nilcase "*":return a * b, nilcase "/":q, _ := div(a, b)return q, nildefault://panic("unsupported operation:" + op)return 0, fmt.Errorf("unsupported operation: %s", op)}
}func div(a, b int) (q,r int) {q = a / br = a % breturn
}
// 在使用除法的时候,我们只使用一个商就够了,不需要用余数,但是这样编辑器会报错的;
// 使用_表示不用的返回值,编辑器就不会报错了
// 一个返回正确数值;一个返回错误
// 1
// Error: unsupported operation: --
函数作为参数
func main() {fmt.Print(apply(pow,3,2))
}
func apply(op func(int, int) int, a, b int) int {// 通过反射拿到函数指针pointer := reflect.ValueOf(op).Pointer()// 获取函数名opName := runtime.FuncForPC(pointer).Name()fmt.Printf("Calling function %s with args (%d,%d) \n",opName,a,b)return op(a,b)
}func pow(a, b int) int {return int(math.Pow(float64(a),float64(b)));
}
// 打印函数信息以及求3的平方
// Calling function main.pow with args (3,2)
// 9
匿名函数
- 不再新建pow函数,直接在传参的时候写一个匿名函数
func main() {fmt.Print(apply(func(a int, b int) int {return int(math.Pow(float64(a), float64(b)))}, 3, 2))
}
func apply(op func(int, int) int, a, b int) int {// 通过反射拿到函数指针pointer := reflect.ValueOf(op).Pointer()// 获取函数名opName := runtime.FuncForPC(pointer).Name()fmt.Printf("Calling function %s with args (%d,%d) \n",opName,a,b)return op(a,b)
}
// 打印函数信息以及求3的平方;因为这个函数是匿名函数所以打印出来的函数名是func1
// Calling function main.main.func1 with args (3,2)
// 9
可变参数
func main() {fmt.Println(sum(1,2,3,4))
}
func sum(numbes ...int) int {res := 0for i := range numbes{res += numbes[i]}return res
}
// 传入1,2,3,4求和
// 10
总结
- 返回值类型写在最后面
- 函数返回多个值的时候可以对返回值起名字,仅用于非常简单的函数,对调用者而言没有区别,仅有一个提示的作用
- go语言的函数可以返回多个值(通常是一个返回值,一个error)
- 函数可以作为参数
- go语言有匿名函数,但是不像java那样有Lambda表达式
- 没有默认参数,可选参数;但是有可变参数
更多推荐
Go学习:函数
发布评论