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中的闭包。
Functions with name are named functions!
说白了,匿名函数是指不需要定义函数名的一种函数实现方式,它并不是一个新概念,最早可以回溯到1958年的Lisp语言。
c++中的匿名函数:
js总的匿名函数:
匿名函数作为返回值
匿名函数付给变量
返回多个匿名函数
完整代码:
输出:
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中使用闭包
返回闭包
Closures and state
陷阱
输出:
index - 3, value - 4
index - 3, value - 4
index - 3, value - 4
index - 3, value - 4
斐波拉切数列
引用:
http://keshavabharadwaj.com/2016/03/31/closure_golang/
在拉勾网上搜索go的职位(北京):
2017年2月14日搜索结果:119个
2017年6月19日搜索结果:163个
2018年1月31日搜索结果:268个
生命不止,继续 go go go !!!
曾记得,某年某月某日,去快手面试。面试官的第一个问题就是:
面试官:“什么是闭包,说一说对闭包的理解”
答:“lambda表达式,其他的不太清楚”
面试官:“lambda表达式是实现闭包的一种方式。”
面试官:“闭包的概念是从JavaScript中开始的”(正确与否,值得商榷)。
今天就聊聊golang中的闭包。
何为匿名函数
匿名函数的英文表示是:Anonymous functionsFunctions 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/
相关文章推荐
- Go实战--Design Patterns in Golang 之单利模式(Singleton)
- Go实战--golang中使用echo框架、MongoDB、JWT搭建REST API(labstack/echo、gopkg.in/mgo.v2、dgrijalva/jwt-go)
- Go实战--Design Patterns in Golang 之工厂模式(简单工厂、工厂方法、抽象工厂)
- Go实战--golang中使用图片和验证码(dchest/captcha)
- Go实战--golang中使用markdown(russross/blackfriday)
- Go实战--golang中OAuth2.0的使用(使用google账号进行登陆验证)
- Go实战--golang中使用echo框架中JSONP(labstack/echo)
- [译] Closures in Lua - Lua中的闭包
- Golang 解决"no buildable Go source file in"问题
- golang实战使用gin+xorm搭建go语言web框架restgo详解4 路由配置
- Go实战--使用golang开发Windows Gui桌面程序(lxn/walk)
- Go实战--golang中使用echo框架中的cors(labstack/echo、rs/cors)
- Go实战--golang生成uuid(The way to go)
- Go实战--golang实现静态文件服务器(文件查看,文件上传,文件下载)
- Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
- golang实战使用gin+xorm搭建go语言web框架restgo详解5 控制器C
- Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
- Go实战--golang新手入门常见错误(The way to go)
- [转][译] Closures in Lua - Lua中的闭包
- Go实战--Golang中http中间件(goji/httpauth、urfave/negroni、gorilla/handlers、justinas/alice)