函数

函数可以定一个多个参数,和不定参数,但是没有默认参数。同样函数可以返回多个值,还可以给返回的值定义名字,同时还支持函数中参数为另一个参数,也支持函数参数为一个匿名函数。

package main

import (
   "fmt"
   "math"
   "reflect"
   "runtime"
)

func eval(a, b int, op string) int{ 
   switch op {
   case "+":
      return a+b
   case "-":
      return a-b
   case "*":
      return a*b
   case "/":
      return a/b
   default:
      panic("不支持的类型 %s" + op)
   }
}

func div(a, b int) (int, int){ // 定义一个函数,两个参数,两个返回值
   return a/b, a%b
}

func div2(a, b int) (q, r int){ // 定义一个函数,两个参数,两个返回值, 两个返回值为分别是 q 和 r
   return a/b, a%b
   /*
   或者可以这么写:(但是这样会增加代码的长度,所以不推荐)
   q = a / b
   r = a % b
   return
    */
}

func div3(a int)(int ,error){  // 定义一个函数,一个参数,返回两个值,一个是 int 另一个是一个 error
   return a, fmt.Errorf("返回错误演示")
}

func apply(op func(int ,int) int, a, b int) int { // 定义一个函数 apply,接受三个参数,第一个为一个函数,此函数接受两个值,返回一个 int, 另外两个参数为 int 类型
   p := reflect.ValueOf(op).Pointer()  // reflect 为反射,Pointer为获取函数的指针
   opName := runtime.FuncForPC(p).Name() // 获取函数的名称
   fmt.Printf("调用的函数为 %s, 参数为 (%d, %d)", opName, a,b)
   return op(a, b)
}

func pow(a, b int) int { // 相当于重写一个 Pow 函数,现在的函数参数为两个 int 值, 返回值为一个 int。之前参数为两个 float64,返回值也为 float64
   return int(math.Pow(float64(a), float64(b)))
}

func sum(numbers ...int) int { // numbers 是一个不定的参数,类型为 int,函数的返回值也为 int
   s := 0
   for i:= range numbers {
      s += numbers[i]
   }
   return s
}

func main(){
   fmt.Println(
      eval(3, 4 , "+"),
      eval(3, 4 , "-"),
      eval(3, 4 , "*"),
      eval(3, 4 , "/"),
      // eval(3, 4 , "%"),
      )

   fmt.Println(div(1, 2))
   q, r := div2(2,3) // 当只想接受一个返回值的时候, 我们可以使用 _ 来忽略不需要的那个值
   fmt.Println(q, r)

   if result1, result2 := div3(1); result2 != nil{
      fmt.Println(result2)
   }else{
      fmt.Println(result1)
   }

   fmt.Println(apply(pow, 3, 4)) // 这里是将函数定义在外面

   fmt.Println(apply(func(i int, i2 int) int { // 这里是将函数定义在参数中,传递的是一个匿名函数
      return int(math.Pow(float64(i), float64(i2)))
   }, 3, 4))

   fmt.Println(sum(1,2,3,3,4,4,5,5,5,6)) // numbers 为不定参数
}