package main

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

/* 返回值 ，可把错误直接返回，不让程序中断执行 */
func eval(a, b int, op string) (int, error) {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":

		// 返回多个值时，可用下划线 _ 代替不需要的返回值
		q, _ := div(78, 9)
		return q, nil
	default:
		// 程序出错，中断执行
		//panic(" unsupported opertion:"+op)
		return 0, fmt.Errorf(" unsupported opertion:%s", op)
	}
}

/*返回两个值*/
func div(a, b int) (q, r int) {
	return a / b, a % b
}

/* op 为入的函数*/
func apply(op func(int, int, string) (int, error), a, b int, o string) int {
	// 获取被调用的函数名
	p := reflect.ValueOf(op).Pointer() // 获取函数指针
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf(" calling function %s with args (%d,%d)", opName, a, b)
	if result, err := op(a, b, o); err != nil {
		return 0
	} else {
		return result
	}
}
func swap(a, b *int) {
	*b, *a = *a, *b
}

func main() {

	if result, error := eval(3, 6, "x"); error != nil {
		fmt.Printf("error:%s", error)
	} else {
		fmt.Println(result)
	}

	fmt.Println(eval(0, 545, "/"))

	fmt.Println(div(15, 9))
	// 第一种调用方式
	fmt.Println(apply(eval, 3, 4, "+"))
	//匿名函数方式
	fmt.Println(
		apply(
			func(a int, b int, o string) (int, error) {
				if a == 0 {
					return 0, fmt.Errorf("xxxxxxxx %s", o)
				}
				return a + b, nil
			},
			100,
			90,
			"+",
		),
	)

	a, b := 10, 20
	swap(&a, &b)
	fmt.Println(a, b)

}
