2,190
社区成员
发帖
与我相关
我的任务
分享
// 伪代码
conn, _ := listener.Accept()
go func() {
data, _ := conn.Read()
// echo
conn.Write(data)
}()
[/quote]
这段代码不够严谨,比如conn应该作为参数传给闭包,而且需要检查错误等等。
不过这只是一个示例,大概知道意思就好。
// 伪代码
conn, _ := listener.Accept()
go func() {
data, _ := conn.Read()
// echo
conn.Write(data)
}()
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函数,直到对象用完才完成生命周期。
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里面管道的作用,可以把一些独立的功能组合连接起来。
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]
原来可以这样用,就是平时用到很少吧?
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))
}