欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GO学习笔记04

程序员文章站 2022-07-16 13:27:06
...

一、函数

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