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 变量的闭包” 。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐