go语言基础

37 阅读2分钟

函数

形参类型一样可以只写一个

func add(x, y int) int {
    return x + y
}
​
func main() {
    fmt.Println(add(42, 13))
}

可返回多个值

func swap(x, y string) (string, string) {
    return y, x
}
​
func main() {
    a, b := swap("hello", "world")
}

返回值是可以被命名

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

函数可赋给变量

func f() {
    fmt.Println("awd")
}
var a = f
func main() {
    a()
}

函数可作为形参/返回值

func f(n1 int, n2 int) int {
    return n1+n2
}
func f1(f func(int, int) int,a int,b int) int {
    return f(a,b)
}
func main() {
    fmt.Println(f1(f,1,2))
}

defer

defer后面必须是函数调用语句,不能是其他语句

原理:将defer语句后面的函数调用的地址压进一个栈中,在当前的函数执行完毕,CPU即将执行函数外的下一行代码之前,先把栈中的指令地址弹出给CPU执行,直到栈为空,才结束这个函数,继续执行后面的代码

func f1(a int) func(int) int {
    var n int = a
    defer fmt.Printf("n1=%d\n", n)
    defer fmt.Printf("n2=%d\n", n+1)
    return func(x int) int {
        n = n + x
        return n
    }
}
func main() {
    f := f1(1)  //执行结果前两行
    fmt.Println(f(1)) //执行结果第三行
    fmt.Println(f(1)) //执行结果第四行
}
//  n2=2
    n1=1
    2
    3

匿名函数

//使用一次  
    re := func(n1, n2 int) int {
        return n1 + n2
    }(1, 2)
    fmt.Println(re)
//使用多次
    re := func(n1, n2 int) int {
        return n1 + n2
    }
    fmt.Println(re(1,2))
//全局匿名函数
var(
    Fun=func (n1,n2 int) int {
        return n1+n2
    }
)
func main() {
    i := Fun(1, 2)
}

闭包

一个函数和与其相关引用环境组合的整体

func f1() func(int) int {
    var n int = 1
    return func(x int) int {
        n = n + x
        return n
    }
}
func main() {
    f := f1()
    fmt.Println(f(1))  //2
    fmt.Println(f(1))  //3
}

错误处理

defer recover

func f1() {
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println(err)  //打印错误信息
        }
    }()
    var n=0;
    var i = 10 / n
    fmt.Println(i)
}

自定义错误

errors.New("错误说明") 和 panic

    err2 := errors.New("不能除0")  //类似throw new xxx("xxx")
    fmt.Print(err2)  //程序继续
    
    panic("错误信息")  //程序终止