闭包 3个月前

编程语言
119
闭包

函数编程之闭包漫谈(Closure)

函数是什么

>>> def ExFunc(n):
     sum=n
     def InsFunc():
             return sum+1
     return InsFunc

>>> myFunc=ExFunc(10)
>>> myFunc()
>>> myAnotherFunc=ExFunc(20)
>>> myAnotherFunc()
>>> myFunc()
>>> myAnotherFunc()
>>>

在这段程序中,函数InsFunc是函数ExFunc的内嵌函数,并且是ExFunc函数的返回值。我们注意到一个问题:内嵌函数InsFunc中引用到外层函数中的局部变量sum,IronPython会这么处理这个问题呢?先让我们来看看这段代码的运行结果。当我们调用分别由不同的参数调用ExFunc函数得到的函数时(myFunc(),myAnotherFunc()),得到的结果是隔离的,也就是说每次调用ExFunc函数后都将生成并保存一个新的局部变量sum。其实这里ExFunc函数返回的就是闭包。

『纯』的函数是没有状态的,加入了闭包以后就变成有状态的了,相对于一个有成员变量的类实例来说,闭包中的状态值不是自己管理,可以认为是『上帝』在管理。

  • 动态作用域,词法作用域
  • 把数据和作用域绑定到一起就是闭包。
  • 将一个上下文的私有变量的生命周期延长的机制。
  • 调用了局部变量函数就是闭包!

引用环境

按照命令式语言的规则,ExFunc函数只是返回了内嵌函数InsFunc的地址,在执行InsFunc函数时将会由于在其作用域内找不到sum变量而出错。而在函数式语言中,当内嵌函数体内引用到体外的变量时,将会把定义时涉及到的引用环境和函数体打包成一个整体(闭包)返回。现在给出引用环境的定义就容易理解了:引用环境是指在程序执行中的某个点所有处于活跃状态的约束(一个变量的名字和其所代表的对象之间的联系)所组成的集合。闭包的使用和正常的函数调用没有区别。

由于闭包把函数和运行时的引用环境打包成为一个新的整体,所以就解决了函数编程中的嵌套所引发的问题。如上述代码段中,当每次调用ExFunc函数时都将返回一个新的闭包实例,这些实例之间是隔离的,分别包含调用时不同的引用环境现场。不同于函数,闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

val string = "HelloWorld"
// 闭包:函数的运行环境
// 函数的作用域没有被释放,作用域包含了函数运行的状态、变量、本地类、本地函数,这个作用域就是闭包
fun makeFun(): ()->Unit // ()->Unit 函数是 makeFun() 的返回值,即函数的返回值是一个函数
// makeFun()的函数体
{
    var count = 0
    return fun(){
        println(++count)
    }
}

fun fibonacci(): Iterable<Long>{
    var first = 0L
    var second = 1L
    return Iterable {
        object : LongIterator(){
            override fun nextLong(): Long {
                val result = second
                second += first
                first = second - first
                return result
            }

            override fun hasNext() = true

        }

    }
}

fun main(args: Array<String>) {
   val add5 = add(5)
    println(add5(2))
}

//fun add(x: Int) = fun(y: Int) = x + y

fun add(x: Int): (Int)-> Int{

    data class Person(val name: String, val age: Int)

    return fun(y: Int): Int{
        return x + y
    }
}
image
EchoEcho官方
无论前方如何,请不要后悔与我相遇。
1377
发布数
439
关注者
2222727
累计阅读

热门教程文档

Javascript
24小节
MySQL
34小节
Java
12小节
Next
43小节
Lua
21小节