• Go基础---->go的基础学习(二)


      这里记录的是go中函数的一些基础知识。道听途说终是浅,身临其境方知深。

    go的基础知识

     一、go中函数的基础使用

    package main 
    
    import (
        "fmt"
        "errors"
    )
    
    func add(a int, b int) (ret int, err error) {
        if a < 0 || b < 0 {
            err = errors.New("Should be non-negative numbers!")
            return
        }
        return a + b, nil
    }
    
    // 不定参数类型
    func myFunc(args ...int) int {
        var result int
        for _, arg := range args {
            result += arg
        }
        return result
    }
    
    func main() {
        result, err := add(3, 4)
        fmt.Println(result, err) // 7 <nil>
    
        fmt.Println(add(-1 ,34)) // 0 Should be non-negative numbers!
    
        fmt.Println(myFunc(1, 3, 5, 7)) // 16
    }

     二、go中的关于匿名函数的使用

    package main 
    
    import "fmt"
    
    func main() {
        // 匿名函数赋值给一个变量
        f := func (x, y int) int {
            return x + y
        }
        fmt.Println(f(3, 45)) // 48
    
        // 匿名函数直接执行
        var result = func (x, y int) int {
            return x - y
        }(45, 6)
        fmt.Println(result) // 39
    }

    三、go中闭包的使用

    Go的匿名函数是一个闭包,闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义。

     一个比较好的例子可以参考一下:http://blog.csdn.net/u012296101/article/details/48525605

    package main
    
    import "fmt"
    
    func adder() func(int) int {
        sum := 0
        return func (x int) int {
            fmt.Println(">>>>>", sum)
            sum += x
            return sum
        }
    }
    
    func main() {
        pos, neg := adder(), adder()
        for i := 0; i < 10; i++ {
            fmt.Println(pos(i), neg(-2 * i))
        }
    }

     运行的效果如下:

    >>>>> 0
    >>>>> 0
    0 0
    >>>>> 0
    >>>>> 0
    1 -2
    >>>>> 1
    >>>>> -2
    3 -6
    >>>>> 3
    >>>>> -6
    6 -12
    >>>>> 6
    >>>>> -12
    10 -20
    >>>>> 10
    >>>>> -20
    15 -30
    >>>>> 15
    >>>>> -30
    21 -42
    >>>>> 21
    >>>>> -42
    28 -56
    >>>>> 28
    >>>>> -56
    36 -72
    >>>>> 36
    >>>>> -72
    45 -90

    四、go中的defer关键字

    package main 
    
    import (    
        "fmt"
    )
    
    func main() {
        defer fmt.Println("before execute")
        fmt.Println("my name is LL.")
        defer fmt.Println("after execute")
    }

    运行的结果:

    my name is LL.
    after execute
    before execute

     defer函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用。

    五、panic() 和 recover()的函数

    package main
    
    import (
        "fmt"
    )
    
    // 最简单的例子
    func SimplePanicRecover() {
        defer func() {
            if err := recover(); err != nil {
                fmt.Println("Panic info is: ", err)
            }
        }()
        panic("SimplePanicRecover function panic-ed!")
    }
    
    // 当 defer 中也调用了 panic 函数时,最后被调用的 panic 函数的参数会被后面的 recover 函数获取到
    // 一个函数中可以定义多个 defer 函数,按照 FILO 的规则执行
    func MultiPanicRecover() {
        defer func() {
            if err := recover(); err != nil {
                fmt.Println("Panic info is: ", err)
            }
        }()
        defer func() {
            panic("MultiPanicRecover defer inner panic")
        }()
        defer func() {
            if err := recover(); err != nil {
                fmt.Println("Panic info is: ", err)
            }
        }()
        panic("MultiPanicRecover function panic-ed!")
    }
    
    // recover 函数只有在 defer 函数中被直接调用的时候才可以获取 panic 的参数
    func RecoverPlaceTest() {
        // 下面一行代码中 recover 函数会返回 nil,但也不影响程序运行
        defer recover()
        // recover 函数返回 nil
        defer fmt.Println("recover() is: ", recover())
        defer func() {
            func() {
                // 由于不是在 defer 调用函数中直接调用 recover 函数,recover 函数会返回 nil
                if err := recover(); err != nil {
                    fmt.Println("Panic info is: ", err)
                }
            }()
    
        }()
        defer func() {
            if err := recover(); err != nil {
                fmt.Println("Panic info is: ", err)
            }
        }()
        panic("RecoverPlaceTest function panic-ed!")
    }
    
    // 如果函数没有 panic,调用 recover 函数不会获取到任何信息,也不会影响当前进程。
    func NoPanicButHasRecover() {
        if err := recover(); err != nil {
            fmt.Println("NoPanicButHasRecover Panic info is: ", err)
        } else {
            fmt.Println("NoPanicButHasRecover Panic info is: ", err)
        }
    }
    
    // 定义一个调用 recover 函数的函数
    func CallRecover() {
        if err := recover(); err != nil {
            fmt.Println("Panic info is: ", err)
        }
    }
    
    // 定义个函数,在其中 defer 另一个调用了 recover 函数的函数
    func RecoverInOutterFunc() {
        defer CallRecover()
        panic("RecoverInOutterFunc function panic-ed!")
    }
    
    func main() {
        SimplePanicRecover()
        MultiPanicRecover()
        RecoverPlaceTest()
        NoPanicButHasRecover()
        RecoverInOutterFunc()
    }

    运行的结果如下:

    Panic info is:  SimplePanicRecover function panic-ed!
    Panic info is:  MultiPanicRecover function panic-ed!
    Panic info is:  MultiPanicRecover defer inner panic
    Panic info is:  RecoverPlaceTest function panic-ed!
    recover() is:  <nil>
    NoPanicButHasRecover Panic info is:  <nil>
    Panic info is:  RecoverInOutterFunc function panic-ed!

    可以参考博客:http://www.cnblogs.com/ghj1976/archive/2013/02/11/2910114.html

    友情链接

  • 相关阅读:
    C# 接口显示实现和隐式实现
    接口压力测试控制台程序
    超全面常用的数据库优化方案
    使用POI导出Excel时,关于设置带有多行表头表格自动宽度的问题解决办法
    win7 64位多出莫名用户,如何去掉?
    MYSQL:frm,myd,myi文件恢复至数据库的方法
    SpringBoot集成Dubbo
    Spring事务传播特性
    搭建Spring源码环境
    JVM常用命令
  • 原文地址:https://www.cnblogs.com/huhx/p/baseusego2.html
Copyright © 2020-2023  润新知