Gox语言中的匿名函数与闭包-GX18

匿名函数就是没有起名字的函数,我们可以把匿名函数赋值给一个变量,否则的话就应该立即调用它,不然定义这个函数就没有意义了。立即调用匿名函数的方法是后面加圆括号和参数(如果有的话)。赋值给变量之后的函数,则可以用变量名加圆括号的方式来调用该函数。

闭包则是在某个函数中返回一个匿名函数,实际上应用场景一般是为了操作在该匿名函数中的一个不想暴露出来的局部变量,有点儿类似面向对象中对数据的“封装”。

下面的例子先后演示了匿名函数的用法和闭包的实现。其中,匿名函数传入的参数又是一个匿名函数。

fn(x) {
    return fn(y) {
        x(y)
    }
}(fn(z) {
        println("Hi!", z)
    })("Nice to see you.")

NewAddFunc = fn() {
    count = 0

    return fn(n) {
        count += n

        return count
    }
}

main {
    println("count=", count)

    f2 = NewAddFunc()
    
    println(f2(3))
        
    println(f2(5))
    
    println(f2(9))
    
    count += 20
    
    println("count=", count)
    
}




这段代码的执行结果是:

λ gox anonymousFunc.gox
Hi! Nice to see you.
count= <nil>
3
8
17
failed to execute script(anonymousFunc.gox) error: unsupported operator: nil+int

可以看出,首先,前半部分定义的匿名函数被正确执行了。然后,后半部分定义的闭包也被正确执行了,证据就是在匿名函数中定义的局部变量count的数值被保留了,并且每次增加也是有效的。

如果没有闭包,一般来说某个函数内部定义的局部变量会被立即释放,但使用闭包之后,可以看出,该变量(count)实际上被保留在内存中了,但又没有开放给外界,只能通过调用NewAddFunc函数获得的匿名函数才能操作该变量,这就是闭包的意义所在。

另外注意本例代码中使用的Gox语言中main函数的写法,比较特殊,使用main函数的好处是可以让其中的变量不要与其他函数中的变量混淆。


* 注:由于0.988版本后,为了减少不必要的文件体积,Gox已经放弃了其他脚本引擎,仅支持Qlang引擎,因此本文中有关其他脚本引擎的内容已经无效,仅留作对旧版本的参考。

下面是匿名函数和闭包样例的Anko引擎版本,Anko引擎版本的代码可以以.ank作为文件名后缀或者在代码开始第一行以// anko开始即可。

// anko

func(x) {
    return func(y) {
        x(y)
    }
}(func(z) {
        println("Hi!", z)
    })("Nice to see you.")

NewAddFunc = func() {
    var count = 0

    return func(n) {
        count += n

        return count
    }
}

f2 = NewAddFunc()

println(f2(3))
    
println(f2(5))

println(f2(9))

这段代码的执行结果是:

λ gox scripts\anonymousFunc.ank
Hi! Nice to see you.
3
8
17

推荐阅读更多精彩内容