Cangjie 函数式编程:高阶函数与闭包
1. 高阶函数
1.1 定义
高阶函数是指那些可以接受一个或多个 函数作为参数 ,或返回一个 函数作为结果 的函数。
将一个或多个函数作为参数、同时返回一个函数作为结果的函数,显然也是高阶函数。

1.2 函数类型
在 Cangjie 语言中,没有类似于 C++ function 或函数指针这样的机制。
因此,如果希望将函数 作为参数传递 或 作为结果返回,则需要语言为函数提供类似变量、结构体和类那样的类型系统支持,以便能够明确地声明和处理函数类型的参数。
Cangjie 函数类型由 函数的参数类型 和 返回类型 组成。
参数类型使用 () 包裹,参数之间使用 , 分隔;参数类型和返回类型之间使用 -> 连接。
func buildUrl() : URL {
// ...
}
函数类型为 () -> URL
func query(value : JsonValue, path : String) : ArrayList<JsonValue> {
// ...
}
函数类型为 (JsonValue, String) -> ArrayList<JsonValue>
1.3 lambda 表达式
C++ Lambda 表达式采用 [捕获列表] (参数列表) { 函数体 } 的形式,例如 [x, &y] (int a) { return x + y + a; } 。
Cangjie Lambda 表达式结构为 { 参数1 : 类型, 参数2 : 类型, ... => 函数体 } ,参数列表在 => 左侧声明,函数体在右侧实现。
C++ 必须显式通过捕获列表(按值捕获、按引用捕获)声明需要使用的外部变量,否则无法在 Lambda 体内访问非静态局部变量;而 Cangjie 无需显式声明捕获列表。
2. 闭包(closure)
2.1 静态作用域
要理解闭包,首先需要理解一个概念:静态作用域。
静态作用域,指的是函数 / 结构体 / 类在 定义时 所处的词法环境 (即代码结构中的位置)。它的关键特性在于,函数可以访问其定义时所在作用域中的变量和方法;这种权限由函数的定义位置决定,而非调用位置。
当函数内部未定义某个变量,则会沿着定义时的作用域链,逐级向上查找,直到全局作用域。

2.2 访问和捕获
访问 是指函数在运行时,实际读取或修改某个变量的值。
捕获 是指函数在定义时,将 外部作用域中的变量 绑定到自身作用域中,即使外部作用域结束,这些变量仍能被保留、供函数后续使用;被捕获的变量生命周期得到延长。
Cangjie 捕获的本质,通过 引用 保留外部变量。
- 在实例成员函数或属性中,对实例成员变量的访问不属于捕获,其本质是通过 this 指针访问实例成员变量。
- 对全局变量或静态成员变量的访问,不属于捕获。全局变量与静态成员变量始终存在,与捕获的特性无关。
2.3 闭包
如果一个函数(包括 lambda 表达式)捕获了其静态作用域内的变量,则 该 函数 与 其捕获的变量 共同构成闭包。
2.4 闭包捕获 不可变变量 和 可变变量
- 闭包能够捕获 let 声明的变量,并在函数外部保持对其值的访问能力。

输出 20,说明闭包成功捕获不可变变量 num 的值。
- 捕获 var 声明变量的闭包,仅能直接调用,不能赋值给变量、作为参数 / 返回值传递、作为表达式使用。

- 如果一个函数调用了捕获 var 变量的闭包,且此 var 变量不在函数内定义,则该函数也会被标记为 “捕获了 var 变量的闭包” 。

更多推荐




所有评论(0)