@@ -50,7 +50,8 @@
|
||||
- 一旦某次调用里开始使用命名参数,后面的参数就不能再退回位置参数。
|
||||
- 对二进制函数 / 系统函数直接使用命名参数,会报 `named parameter mode can't support here`;这类函数要先用 TSL 再封一层。
|
||||
- 函数参数支持默认值。
|
||||
- 普通函数的默认值规则不要直接等同到 `unit interface` 声明;跨 `unit` 的默认参数边界只照本页最小反例和 [09_units_and_scope.md](09_units_and_scope.md) 处理。
|
||||
- `unit interface` 中的默认参数可以引用该接口中可访问的 `const`;实现函数头不要重复声明默认值。
|
||||
- 默认参数表达式属于新一代 TSL 能力;表达式里引用变量时,该变量按 `0` 求值。面向旧运行时或版本不明时,默认只生成字面量 / 可访问常量默认值。
|
||||
- 尾部 `...` 形式的可变参数属于文档明确写法。
|
||||
- 在可变参数函数体里,`Params`、`ParamCount`、`RealParamCount` 都可用。
|
||||
- 可变参数组可以通过 `...` 转发给另一个函数调用。
|
||||
@@ -61,6 +62,7 @@
|
||||
- 匿名函数和 TSL 函数值的稳定调用方式仍是 `call(f, ...)` 或 `##f(...)`。
|
||||
- `f(...)` 这种“函数变量直接调用”写法不作为可写事实;无论 `f` 是匿名函数、`findFunction(...)` 还是 `thisFunction(...)` 返回的函数指针,都不要默认写成直调。
|
||||
- `::FuncName(...)` 可以指向全局/系统函数,用来绕过当前作用域里的同名局部函数。
|
||||
- `system.FuncName(...)` 专门强制指定系统函数;它与 `::FuncName(...)` 的全局限定语义不要互相替代。
|
||||
- `external`、原生函数指针包装、`makeInstance` / C 回调和线程调用的事实见 [17_external_calls_and_threads.md](17_external_calls_and_threads.md)。
|
||||
- 不要在 `.tsl` 的函数声明区之后继续追加脚本语句。
|
||||
|
||||
@@ -502,7 +504,7 @@ begin
|
||||
end;
|
||||
```
|
||||
|
||||
默认值也可以写成表达式:
|
||||
新一代 TSL 的默认值也可以写成表达式:
|
||||
|
||||
代码块身份:可直接照写示例
|
||||
|
||||
@@ -523,24 +525,56 @@ end;
|
||||
- `Pack(a: 1)` 返回 `12`
|
||||
- `ExprDefault()` 返回 `3`
|
||||
|
||||
`unit interface` 声明下的默认参数要单独看。普通函数默认参数可用,不等于跨 `unit` 声明边界也同样可靠。
|
||||
表达式默认值的版本边界:
|
||||
|
||||
代码块身份:反例 / 不可照写
|
||||
代码块身份:可直接照写示例
|
||||
|
||||
```text
|
||||
unit UnitConst;
|
||||
interface
|
||||
|
||||
const default_value = 888;
|
||||
function F(a, b = 100, c = default_value);
|
||||
```tsl
|
||||
function RefDefault(a, b = a + 1);
|
||||
begin
|
||||
return b;
|
||||
end;
|
||||
```
|
||||
|
||||
边界说明:
|
||||
|
||||
- `F(1)` 输出 `101`,`F(1, 2)` 输出 `3`
|
||||
- 同一组文件下,`UnitConst.default_value` 可读到 `888`,而 `F(1, 2, 3)` 输出 `6`
|
||||
- 因此不要把“普通函数默认参数可用”直接泛化成“`unit interface` 里引用 `unit const` 的默认参数也同样可靠”
|
||||
- 这类跨 `unit` 的声明边界事实见 [09_units_and_scope.md](09_units_and_scope.md)
|
||||
- 在支持默认参数表达式的新一代 TSL 中,`RefDefault(5)` 返回 `1`,因为默认表达式里的变量 `a` 按 `0` 求值
|
||||
- 这项能力自 2025-08-27 后的 NG 客户端 / 新一代 TSL 服务端提供;目标版本不明时不要生成变量参与的默认表达式
|
||||
|
||||
`unit interface` 可以使用接口中可访问的常量作为默认值:
|
||||
|
||||
代码块身份:配置片段 / 概念骨架
|
||||
|
||||
```text
|
||||
// UnitDefaults.tsf
|
||||
unit UnitDefaults;
|
||||
|
||||
interface
|
||||
|
||||
const default_value = 888;
|
||||
function F(a, b = 100, c = default_value);
|
||||
|
||||
implementation
|
||||
|
||||
function F(a, b, c);
|
||||
begin
|
||||
return a + b + c;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
// main.tsl
|
||||
uses UnitDefaults;
|
||||
echo F(1), ",", F(1, 2);
|
||||
```
|
||||
|
||||
代码块身份:输出片段
|
||||
|
||||
```text
|
||||
989,891
|
||||
```
|
||||
|
||||
说明:默认值只在 `interface` 声明处写一次;实现函数头使用同一组形参,但不重复 `= ...`。
|
||||
|
||||
### 可变参数 `...`
|
||||
|
||||
@@ -686,7 +720,12 @@ end;
|
||||
|
||||
<!-- section-id: syntax-05-011 -->
|
||||
|
||||
<!-- tags: lambda, 闭包, 函数当变量, 函数当参数, 回调, 函数指针, 把函数存起来 -->
|
||||
<!-- tags: lambda, 闭包, 函数当变量, 函数当参数, 回调, 函数指针, 把函数存起来, 匿名函数作用域, 对象成员, 宿主函数, 临时变量, 捕获外层变量 -->
|
||||
|
||||
匿名函数作用域边界:
|
||||
|
||||
- 匿名函数定义在类的方法中时,可以访问当前对象的成员和方法。
|
||||
- 匿名函数不能访问宿主函数的临时变量;不要把它当成会捕获外层临时变量的词法闭包。
|
||||
|
||||
匿名函数变量:
|
||||
|
||||
@@ -851,7 +890,26 @@ end;
|
||||
|
||||
<!-- section-id: syntax-05-013 -->
|
||||
|
||||
`external`、原生函数指针包装、`makeInstance` / C 回调和线程调用,统一见 [17_external_calls_and_threads.md](17_external_calls_and_threads.md)。这一篇只保留“普通函数怎样定义和调用”的主线。
|
||||
<!-- tags: system 前缀, 指定系统函数, 绕过同名用户函数, 系统函数限定 -->
|
||||
|
||||
系统函数可能与用户定义函数同名。需要明确指定系统实现时,使用 `system.FuncName(...)`:
|
||||
|
||||
代码块身份:可直接照写示例
|
||||
|
||||
```tsl
|
||||
value := system.strToInt("123");
|
||||
writeLn(value);
|
||||
```
|
||||
|
||||
代码块身份:输出片段
|
||||
|
||||
```text
|
||||
123
|
||||
```
|
||||
|
||||
本节只拥有 `system.` 这一调用限定语法。示例中的真实函数名、签名和目标 scope 必须由 `tsl-api-reference` skill 核对;不要从本节推断任意系统 API。
|
||||
|
||||
`external`、原生函数指针包装、`makeInstance` / C 回调和线程调用,统一见 [17_external_calls_and_threads.md](17_external_calls_and_threads.md)。
|
||||
|
||||
## 默认生成模板
|
||||
|
||||
@@ -906,7 +964,10 @@ end;
|
||||
- 把 `a = 1` 这种比较表达式误当成命名参数调用。
|
||||
- 以为默认值只能用于无类型参数。
|
||||
- 在 `const` 形参上直接赋值。
|
||||
- 把普通函数的默认值规则原样套到 `unit interface` 里的 `const` 默认参数上。
|
||||
- 在旧运行时或版本不明时生成默认参数表达式。
|
||||
- 以为默认参数表达式里的形参会取本次调用实参;其中变量按 `0` 求值。
|
||||
- 在 `unit interface` 和 `implementation` 的函数头上重复写默认值。
|
||||
- 用 `::FuncName(...)` 和 `system.FuncName(...)` 互相替代,而不区分全局限定与系统函数限定。
|
||||
- 把匿名函数或 `findFunction(...)` 返回值默认写成 `f(...)` 直调。
|
||||
- 把命名参数直接套到二进制函数或系统函数上。
|
||||
- 在一次调用里先进入命名参数模式,后面又退回位置参数。
|
||||
@@ -995,7 +1056,7 @@ const default_value = 888;
|
||||
function F(a, b = 100, c = default_value);
|
||||
```
|
||||
|
||||
不要把上面这种 `unit interface` 声明直接当成已经等价于普通函数默认参数规则。按文档结果,对应的 `F(1)` 输出是 `101`,不是按 `default_value = 888` 补成的结果;具体边界见 [09_units_and_scope.md](09_units_and_scope.md)。
|
||||
上面的片段缺少 `implementation` 和 `end.`,因此不能作为完整 `unit` 文件直接照写;它不是“接口常量不能作为默认值”的反例。完整可写结构见本页默认参数章节。
|
||||
|
||||
代码块身份:反例 / 不可照写
|
||||
|
||||
|
||||
Reference in New Issue
Block a user