1、闭包定义(Closure)
来自wiki定义:彼得·兰丁在1964年将术语“闭包”定义为一种包含环境成分和控制成分的实体,用于在他的SECD机器上对表达式求值。 Joel Moses认为是Landin发明了“闭包”这一术语,用来指代某些其开放绑定(自由变量)已经由其语法环境完成闭合(或者绑定)的lambda表达式,从而形成了闭合的表达式,或称闭包。这一用法后来于1975年被Sussman和Steele在定义 Scheme语言的时候予以采纳,并广为流传。
闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。变量的作用域仅限于包含它们的函数,因此无法从其它程序代码部分进行访问。不过,变量的生存期是可以很长,在一次函数调用期间所创建所生成的值在下次函数调用时仍然存在。正因为这一特点,闭包可以用来完成信息隐藏,并进而应用于需要状态表达的某些编程范型中。
不过,用这种方式来使用闭包时,闭包不再具有引用透明性,因此也不再是纯函数。即便如此,在某些“近似于函数式编程语言”的语言,例如Scheme中,闭包还是得到了广泛的使用。
顺便提一嘴:百度百科的经专家鉴定的词条“闭包”,真心看不懂,哎~~~
2、Go Lang中的闭包
斐波那契数列:斐波那契数列是一种数列,它的规律是数列中某一个位置的数字是该位置的前两个位置的数字之和。像这样:0, 1, 1, 2, 3, 5, 8, 13…
那就使用闭包实现数列算法:
package main
import "fmt"
// 1.定义单纯的加法函数
func add(x, y int) int {
return x + y
}
// 2.fibonacci 函数,返回值是一个函数
func fibonacci(s1, s2 int) func() int {
//闭包使用到的环境变量,除初始化外,都会保持值
left := s1
right := s2
return func() int {
next := add(left, right)
left = right
right = next
return next
}
}
func main() {
// 调用一次闭包函数来得到闭包函数的初始化
f := fibonacci(0, 1)
for i := 0; i < 10; i++ {
// 反复不断的调用f得到结果
fmt.Println("next value: ", f())
}
//再来一次新函数初始化,会生成第二个实例
f2 := fibonacci(0, 1)
for i := 0; i < 10; i++ {
// 反复不断的调用f得到结果
fmt.Println("next value: ", f2())
}
}
3、复习对比下Javascript的闭包
// 1.定义单纯的加法函数
function add(x, y) {
return x + y;
}
// 2.fibonacci 函数,返回值是一个函数
function fibonacci(s1, s2) {
//闭包使用到的环境变量,除初始化外,都会保持值
var left = s1;
var right = s2;
return function(){
var next = add(left, right) ;
left = right;
right = next ;
return next;
}
}
// 调用一次闭包函数来得到闭包函数的初始化
var f = fibonacci(0, 1);
for(i = 0; i < 10; i++ ){
// 反复不断的调用f得到结果
console.log("next value: ", f())
}
//再来一次新函数初始化,会生成第二个实例
var f2 = fibonacci(0, 1);
for(i = 0; i < 10; i++ ){
// 反复不断的调用f得到结果
console.log("next value: ", f2())
}
4、结语
go lang的语法啊,还需要多熟悉,很多用法都很生疏,呵呵,慢慢来~~