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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容