GO学习笔记04

一、函数

1.不定参数函数(直接来难的)

    package main
    
    import "fmt"
    
    func MyFunc() {
        fmt.Println("无参数无返回值的函数")
    }
    
    func MyFunc01(a, b int) {
        fmt.Printf("含有两个参数a = %d, b = %d\n", a, b)
    }
    
    //不定参数放在其他参数的最后,不定参数可以根据情况进行传递
    func MyFunc02(args ... int) {
        fmt.Println("参数长度:", len(args))
        for a := 0; a < len(args); a++ {
            fmt.Printf("arg[%d] = %d\n", a, args[a])
        }
        //迭代
        for i, data := range args {
            fmt.Printf("arg[%d] = %d\n", i, data)
        }
    }
    
    func main() {
        MyFunc()
        MyFunc01(88, 99)
        MyFunc02(1, 2, 3, 4)
    }
    
    
    无参数无返回值的函数
    含有两个参数a = 88, b = 99
    参数长度: 4
    arg[0] = 1
    arg[1] = 2
    arg[2] = 3
    arg[3] = 4
    arg[0] = 1
    arg[1] = 2
    arg[2] = 3
    arg[3] = 4

2.参数传递

    package main
    
    import "fmt"
    
    func myfunc(tmp ...int) {
        for _, data := range tmp {
            fmt.Println("data = ", data)
        }
    }
    
    func test(args ...int) {
        //传递所有的参数给myfunc
        myfunc(args[:]...)
        fmt.Println("-----------------")
        myfunc(args[:2]...)
        fmt.Println("-----------------")
        myfunc(args[2:]...)
    }
    
    func main() {
        test(1, 2, 3, 4)
    
    }
    
    data =  1
    data =  2
    data =  3
    data =  4
    -----------------
    data =  1
    data =  2
    -----------------
    data =  3
    data =  4
    

3.有返回值的函数

 package main
    
    import "fmt"
    
    func myfunc01() int {
        return 666
    }
    func myfunc02() (result int) {
        return 777
    }
    
    func myfunc03() (result int) {
        result = 888
        return
    }
    
    func main() {
        var a int
        a = myfunc01()
        fmt.Println("a = ", a)
    
        a =myfunc02()
        fmt.Println("a = ", a)
    
        a =myfunc03()
        fmt.Println("a = ", a)
    
    }

4.函数有多返回值

 package main
    
    import "fmt"
    
    func myfunc01() (int, int, int) {
        return 1, 2, 3
    }
    
    //go推荐写法
    func myfunc02() (a, b, c int) {
        a, b, c = 111, 222, 333
        return
    }
    
    func main() {
        a, b, c := myfunc02()
        fmt.Printf("a = %d, b = %d ,  c = %d\n", a, b, c)
    
    }
    
    a = 111, b = 222 ,  c = 333

5.注意事项

    a.函数名字小写为private 大写即为public
    b.不支持默认参数
    c.如果没有返回值,就直接省略最后的返回信息
    d.如果只有一个值且不声明返回值变量,则可以省略
    e.函数的形参只是声明了两个变量类型,这样也可以

6.有参数有返回值

    package main
    
    import "fmt"
    
    func MaxAndMin(a, b int) (max, min int) {
        if (a > b) {
            max = a
            min = b
        } else {
            max = b
            min = a
        }
        return
    }
    
    func main() {
        max, min := MaxAndMin(10, 20)
        fmt.Printf("max = %d , min = %d\n", max, min)
        
        //匿名变量丢弃某个值
        a, _ := MaxAndMin(10, 20)
        fmt.Printf("a = %d\n", a)
    }
    
    max = 20 , min = 10
    a = 20

7.递归

    package main
    
    import "fmt"
    
    func tests(i int) int {
        if i == 1 {
            return 1
        }
        return i + tests(i-1)
    }
    
    func main() {
        var sum int
        sum = tests(100)
        fmt.Printf("sum = %d\n", sum)
    }
    
    
    sum = 5050

8.函数类型

    package main
    
    import "fmt"
    
    func Add(a, b int) int {
        return a + b
    }
    
    func Minus(a, b int) int {
        return a - b
    }
    
    //函数类型
    type FuncType func(int, int) int
    
    func main() {
        //普通调用
        var result int
        result = Add(1, 2)
        fmt.Printf("result = %d\n", result)
    
        var ftype FuncType
        ftype = Add
        result = ftype(10, 20)
        fmt.Printf("result2 = %d\n", result)
    
        var ftype01 FuncType
        ftype01 = Minus
        result = ftype01(10, 20)
        fmt.Printf("result3 = %d\n", result)
    }
    
    result = 3
    result2 = 30
    result3 = -10

9.回调函数

 package main
    
    import "fmt"
    
    type FuncType01 func(int, int) int
    
    func Add01(a, b int) int {
        return a + b
    }
    
    func Minus01(a, b int) int {
        return a - b
    }
    
    //函数有一个参数是函数类型,这个函数就是回调函数
    func Calc(a, b int, fTest FuncType01) (result int) {
        fmt.Printf("Calc")
        result = fTest(a, b)
        return
    
    }
    
    func main() {
        a := Calc(1, 1, Add01)
        fmt.Printf("a = %d\n", a)
    
        b := Calc(1, 1, Minus01)
        fmt.Printf("b = %d\n", b)
    }
    
    Calca = 2
    Calcb = 0

10.匿名函数

 package main
    
    import "fmt"
    
    func main() {
        a := 10
        str := "mike"
    
        //匿名函数没有函数名字
        f1 := func() {
            fmt.Println("a =", a)
            fmt.Println("str =", str)
        }
        f1()
        fmt.Println("------------")
    
        //起别名
        type FuncType02 func()
        var f2 FuncType02
        f2 = f1
        f2()
        fmt.Println("------------")
    
        //定义匿名函数,同时调用
        func() {
            fmt.Printf("a = %d, str = %s\n", a, str)
        }()
        fmt.Println("------------")
    
        //定义匿名函数,有参数有返回值
        x, y := func(i, j int) (max, min int) {
            if i > j {
                max = i
                min = j
            } else {
                max = j
                min = i
            }
            return
        }(10, 20)
    
        fmt.Printf("x = %d, y = %d\n", x, y)
    
    }
    
    
    a = 10
    str = mike
    ------------
    a = 10
    str = mike
    ------------
    a = 10, str = mike
    ------------
    x = 20, y = 10

11.闭包

    package main
    
    import "fmt"
    
    func main() {
        a := 10
        str := "hello"
    
        func() {
            //闭包以引用方式捕获外部变量
            a = 999
            str = "go"
            fmt.Printf("内部 a = %d, str = %s\n", a, str)
        }()
    
        fmt.Printf("外部 a = %d, str = %s\n", a, str)
    
    }
    内部 a = 999, str = go
    外部 a = 999, str = go

12.闭包的特点

    package main
    
    import "fmt"
    
    //返回是一个匿名函数,返回一个函数类型
    func fun() func() int {
        var x int
        return func() int {
            x++
            return x * x
        }
    }
    
    func main() {
        //特点:
        //它不关心这些捕获了的变量和常量是否已经超出了作用域
        //所以只有闭包还在使用它,这些变量就还会存在
        f := fun()  
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
    }
    
    1
    4
    9
    16
    25

12.defer的延迟调用

        defer fmt.Println("11111111111111")
        fmt.Println("22222222222222")
        
        22222222222222
        11111111111111

13.多个defer的调用顺序

    package main
    
    import "fmt"
    
    func fun(x int) {
        result := 100 / x
        fmt.Println("resut =", result)
    }
    
    func main() {
        defer fmt.Println("11111111111111")
        defer fmt.Println("22222222222222")
        defer fun(0)
        defer fmt.Println("3333333333333")
    }
    
    
    3333333333333
    22222222222222
    11111111111111
    panic: runtime error: integer divide by zero
    
    goroutine 1 [running]:
    main.fun(0x0)
        /Users/xxx/GOLang/demo01/02/09.go:7 +0xe4
    main.main()
        /Users/xxx/GOLang/demo01/02/09.go:19 +0x179

14.defer和匿名函数的混合使用

    package main
    
    import "fmt"
    
    func main() {
        a := 10
        b := 20
        defer func() {
            fmt.Printf("a = %d, b = %d\n", a, b)
        }()
    
        a = 111
        b = 333
        fmt.Printf("外部的:a = %d, b = %d\n", a, b)
    
    }
    
    
    外部的:a = 111, b = 333
    a = 111, b = 333

和下面的区别

    package main
    
    import "fmt"
    
    func main() {
        a := 10
        b := 20
        defer func(a, b int) {
            fmt.Printf("a = %d, b = %d\n", a, b)
        }(a, b)
    
        a = 111
        b = 333
        fmt.Printf("外部的:a = %d, b = %d\n", a, b)
    
    }
    
    外部的:a = 111, b = 333
    a = 10, b = 20

你可能感兴趣的:(GO学习笔记04)