Golang闭包和匿名函数

1. 匿名函数

匿名函数就是没有函数名的函数,以下所示。闭包

func test() int {
    max := func(a, b int) int {
        if a > b {
            return a
        } else {
            return b
        }
    }(3, 4)
    return max
}

func main() {
    primeCnt := make(chan int, 1)
    N := 10
    go func(N int) {
        cnt := 0
        for i := 2; i < N; i++ {
            var j int
            for j = 2; j <= int(math.Sqrt(float64(i))); j++ {
                if i%j == 0 {
                    break
                }
            }
            if j > int(math.Sqrt(float64(i))) {
                cnt++
                fmt.Println(i)
            }
        }
        primeCnt <- cnt
    }(N)
    fmt.Println("totalNum:", <-primeCnt)
}

基本上匿名函数也没啥好说的 。。。函数

2. 闭包

闭包感受就是返回值为匿名函数的函数。。。来看个例子吧 (◉3◉)工具

package main

import (
    "fmt"
)

func squares() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}

func main() {
    f := squares()
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
}

运行结果以下所示,能够看到三次调用f(),得到的是不一样的x。即使是x是squares的局部变量,可是变量x的生命周期被延长到了三次函数调用( f() )。这是为何呢?让咱们在看看另外一种状况。post

package main

import (
    "fmt"
)

func squares() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}

func main() {
    f := squares()
    f1 := squares()
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())

    fmt.Println(f1())
    fmt.Println(f1())
    fmt.Println(f1())
}

 

看到了吧。换个变量就又从新开始了。嘿嘿嘿。为何会这样,一句话,内存逃逸。什么是内存逃逸,简单地说就是原本在栈上的变量又跑到堆里去了。固然这么讲过于简单了,改天再写一文谈谈内存逃逸给各位太君,嘿嘿嘿。那么怎么才能检测程序有没有发生内存逃逸呢。go build工具就欧克了。以下图所示。ui

从图中咱们能够看到变量x被移动到了堆中,这也就解释了为何x的生命周期能够被延长。spa

 

参考

http://www.javashuo.com/article/p-duhoryld-gs.html 关于闭包的分析设计

《Go程序设计语言》code

https://www.do1618.com/archives/1328/go-%E5%86%85%E5%AD%98%E9%80%83%E9%80%B8%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90/ 关于内存逃逸的分析blog

相关文章
相关标签/搜索