您的位置:首页 > 编程语言 > Go语言

Go实战--Closures in golang(匿名函数、闭包)

2018-01-31 14:51 633 查看
号外!!号外!!

在拉勾网上搜索go的职位(北京):

2017年2月14日搜索结果:119个

2017年6月19日搜索结果:163个

2018年1月31日搜索结果:268个

生命不止,继续 go go go !!!

曾记得,某年某月某日,去快手面试。面试官的第一个问题就是:

面试官:“什么是闭包,说一说对闭包的理解”

答:“lambda表达式,其他的不太清楚”

面试官:“lambda表达式是实现闭包的一种方式。”

面试官:“闭包的概念是从JavaScript中开始的”(正确与否,值得商榷)。

今天就聊聊golang中的闭包。

何为匿名函数

匿名函数的英文表示是:Anonymous functions

Functions with name are named functions!

说白了,匿名函数是指不需要定义函数名的一种函数实现方式,它并不是一个新概念,最早可以回溯到1958年的Lisp语言。

c++中的匿名函数:

auto a_lambda_func = [](int x)


js总的匿名函数:

function(argument1,argument2){
}


golang中匿名函数

定义匿名函数

func(x,y int) int {
return x + y
}


匿名函数作为返回值

func getPrintMessage() func(string) {
// returns an anonymous function
return func(message string) {
fmt.Println(message)
}
}


匿名函数付给变量

f := func() int {
...
}


返回多个匿名函数

func calc(x, y int) (func(int), func()) {
f1 := func(z int) int {
return (x + y) * z / 2
}

f2 := func() int {
return 2 * (x + y)
}
return f1, f2
}


完整代码:

package main

import "fmt"

func printMessage(message string) {
fmt.Println(message)
}

func getPrintMessage() func(string) { // returns an anonymous function return func(message string) { fmt.Println(message) } }

func main() {
// named function
printMessage("Hello function!")

// anonymous function declared and called
func(message string) {
fmt.Println(message)
}("Hello anonymous function!")

// gets anonymous function and calls it
printfunc := getPrintMessage()
printfunc("Hello anonymous function using caller!")

}


输出:

Hello function!

Hello anonymous function!

Hello anonymous function using caller!

何为闭包

关于闭包的概念,有些抽象。

WIKI:

In programming languages, closures (also lexical closures or function closures) are techniques for implementing lexically scoped name binding in languages with first-class functions.

A closure is a function value that references variables from outside its body.

个人理解:

闭包就是能够读取其他函数内部变量的函数。

只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成”定义在一个函数内部的函数”。

golang中使用闭包

package main

import "fmt"

func outer(name string) {
// variable in outer function
text := "Modified " + name

// foo is a inner function and has access to text variable, is a closure
// closures have access to variables even after exiting this block
foo := func() {
fmt.Println(text)
}

// calling the closure
foo()
}

func main() {
outer("hello")
}


返回闭包

package main

import "fmt"

func outer(name string) func() {
// variable
text := "Modified " + name

// closure. function has access to text even after exiting this block
foo := func() {
fmt.Println(text)
}

// return the closure
return foo
}

func main() {
// foo is a closure
foo := outer("hello")

// calling a closure
foo()
}


Closures and state

package main

import "fmt"

func counter(start int) (func() int, func()) {
// if the value gets mutated, the same is reflected in closure
ctr := func() int {
return start
}

incr := func() {
start++
}

// both ctr and incr have same reference to start
// closures are created, but are not called
return ctr, incr
}

func main() {
// ctr, incr and ctr1, incr1 are different
ctr, incr := counter(100)
ctr1, incr1 := counter(100)
fmt.Println("counter - ", ctr())
fmt.Println("counter1 - ", ctr1())
// incr by 1
incr()
fmt.Println("counter - ", ctr())
fmt.Println("counter1- ", ctr1())
// incr1 by 2
incr1()
incr1()
fmt.Println("counter - ", ctr())
fmt.Println("counter1- ", ctr1())
}


陷阱

package main

import "fmt"

func functions() []func() {
// pitfall of using loop variables
arr := []int{1, 2, 3, 4}
result := make([]func(), 0)

for i := range arr {
result = append(result, func() { fmt.Printf("index - %d, value - %d\n", i, arr[i]) })
}

return result
}

func main() {
fns := functions()
for f := range fns {
fns[f]()
}
}


输出:

index - 3, value - 4

index - 3, value - 4

index - 3, value - 4

index - 3, value - 4

斐波拉切数列

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
x, y := 0, 1
return func() int {
x, y = y, x+y
return x
}
}

func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}


引用:

http://keshavabharadwaj.com/2016/03/31/closure_golang/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: