闭包是什么?怎么用?

aotian16 2014-03-04 08:32:36
加精
百度上看了下,就是带自由变量的函数.
没感觉出来有什么用啊?

请指教!
...全文
3043 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Bug开发攻城狮 2016-06-22
  • 打赏
  • 举报
回复
javascript语言中,闭包是为了,访问方法中的变量,即函数中的函数
qq_1021540607 2016-06-22
  • 打赏
  • 举报
回复
keen_ 2014-06-15
  • 打赏
  • 举报
回复
在我认识里,闭包就是对象的封装。 a := func(){...} a() 而封装意味着给出一定的接口,当我们需要喂一个对象给高阶函数的调用的时候,匿名函数就可以给出符合要求的形式化接口。 在多数情况下,匿名函数的存在都是为了给出一定的形式化接口,我想这就是它的作用吧。 干脆把闭包视为对象就是了。
svenwang 2014-03-10
  • 打赏
  • 举报
回复
引用 4 楼 svenwang 的回复:
[quote=引用 2 楼 aotian16 的回复:] 多谢版主,概念是有点懂 就是不知道实用性,什么情况下会用到啊?
或者你想并发执行一个代码块,但是重写一个函数又很麻烦:

// 伪代码
conn, _ := listener.Accept()
go func() {
	data, _ := conn.Read()
	// echo
	conn.Write(data)
}()
[/quote] 这段代码不够严谨,比如conn应该作为参数传给闭包,而且需要检查错误等等。 不过这只是一个示例,大概知道意思就好。
svenwang 2014-03-10
  • 打赏
  • 举报
回复
引用 2 楼 aotian16 的回复:
多谢版主,概念是有点懂 就是不知道实用性,什么情况下会用到啊?
或者你想并发执行一个代码块,但是重写一个函数又很麻烦:

// 伪代码
conn, _ := listener.Accept()
go func() {
	data, _ := conn.Read()
	// echo
	conn.Write(data)
}()
threenewbee 2014-03-10
  • 打赏
  • 举报
回复
闭包其实很简单,就是说匿名高阶函数可以直接访问作用域外面的变量,而外面的变量不能访问里面的变量。 我用C#举例:
void Main()
{
    int x = 1;
    Func<int> foo = new Func<int>(() => 
    {
        Console.WriteLine(x); // 1
        int y = 2;
        return x + y;
    });
    int z = foo();
    Console.WriteLine(z); // 3
    // Console.WriteLine(y); error
}
很简单,就是匿名函数可以访问到x,x是在Main函数中调用的。但是显然Main函数不能访问y。 闭包写法很便利,如果没有闭包,我们必须手工将x传入匿名函数。如果涉及修改,还得让匿名函数传出修改后的x,主程序再修改之。 但是闭包也有副作用,就是会延长变量的生命周期,比如
private Func<int> foo;
void Main()
{
    int x = 1;
    foo = new Func<int>(() => 
    {
        return x;
    });
}
按理说,x在Main函数运行完了就不存在了。但是它会被foo这个匿名函数用到。而foo是一个成员变量。所以x会被“带出”Main函数,直到对象用完才完成生命周期。
svenwang 2014-03-10
  • 打赏
  • 举报
回复
引用 6 楼 aotian16 的回复:
[quote=引用 3 楼 svenwang 的回复:] [quote=引用 2 楼 aotian16 的回复:] 多谢版主,概念是有点懂 就是不知道实用性,什么情况下会用到啊?
比如你想创建一个高阶函数的时候就很有用

package main

import (
	"fmt"
)

func combine(f1, f2 func(int) int) func(int) int {
	return func(n int) int {
		return f1(f2(n))
	}
}

func inc(n int) int {
	return n + 1
}

func square(n int) int {
	return n * n
}

func main() {
	f1 := combine(inc, square)
	f2 := combine(square, inc)
	fmt.Println(f1(10))
	fmt.Println(f2(10))
}
[/quote] 原来可以这样用,就是平时用到很少吧?[/quote] 比较少,但还是偶尔会用到。 再举个例子,比如有一个打开文件的函数,还有一个解压缩的函数,那就可以创建一个高阶函数把前面两个函数组合起来,提供给用户一个用于打开压缩文件的函数。这里的高阶函数有点类似unix里面管道的作用,可以把一些独立的功能组合连接起来。
aotian16 2014-03-10
  • 打赏
  • 举报
回复
引用 3 楼 svenwang 的回复:
[quote=引用 2 楼 aotian16 的回复:] 多谢版主,概念是有点懂 就是不知道实用性,什么情况下会用到啊?
比如你想创建一个高阶函数的时候就很有用

package main

import (
	"fmt"
)

func combine(f1, f2 func(int) int) func(int) int {
	return func(n int) int {
		return f1(f2(n))
	}
}

func inc(n int) int {
	return n + 1
}

func square(n int) int {
	return n * n
}

func main() {
	f1 := combine(inc, square)
	f2 := combine(square, inc)
	fmt.Println(f1(10))
	fmt.Println(f2(10))
}
[/quote] 原来可以这样用,就是平时用到很少吧?
svenwang 2014-03-09
  • 打赏
  • 举报
回复
引用 2 楼 aotian16 的回复:
多谢版主,概念是有点懂 就是不知道实用性,什么情况下会用到啊?
比如你想创建一个高阶函数的时候就很有用

package main

import (
	"fmt"
)

func combine(f1, f2 func(int) int) func(int) int {
	return func(n int) int {
		return f1(f2(n))
	}
}

func inc(n int) int {
	return n + 1
}

func square(n int) int {
	return n * n
}

func main() {
	f1 := combine(inc, square)
	f2 := combine(square, inc)
	fmt.Println(f1(10))
	fmt.Println(f2(10))
}
十一文 2014-03-07
  • 打赏
  • 举报
回复
wiki上的说法: 在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。 https://zh.wikipedia.org/w/index.php?title=%E9%97%AD%E5%8C%85_%28%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6%29&variant=zh-cn ----- 我的理解: 1.有一个私有作用域,可以防止作用域被污染,可参考javascript 2.当外部变量对象没销毁,闭包引用的外部变量对象没有被销毁
aotian16 2014-03-07
  • 打赏
  • 举报
回复
多谢版主,概念是有点懂 就是不知道实用性,什么情况下会用到啊?

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧