全屏浏览
缩小浏览
回到页首

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

 

友情链接

 

posted @ 2017-06-22 17:01  huhx  阅读(249)  评论(0编辑  收藏  举报