Files
tsl-devkit/docs/tsl/syntax/05_variables_and_constants.md
T
csh 3d83740f88 Squashed 'docs/standards/playbook/' changes from c3f8137..25d895d
25d895d 🐛 fix(gitea_workflow): clean up temp repos after job steps
2bc3b11 🐛 fix(gitea_workflow): clean up temporary repo dirs in workflows
98c3f30 📝 docs(agent_rules): allow plan execution on current branch
16c7230 📝 docs(prompts): define custom verify layering
8efc4dd 🐛 fix(skills): quote commit-message description
bc8498f 🐛 fix(ci): install tomli for gitea tests
55cda3b 🐛 fix(tests): report missing toml parser clearly
c0729c7 🐛 fix(playbook): import Optional for cli compatibility
63e24bf 📦 deps(skills): sync thirdparty skills
d2f9356 🐛 fix(ci): isolate gitea workflow repos
588b81d 🐛 fix(ci): inline gitea workflow bootstrap
e0b1c3a ♻️ refactor(skills): standardize first-party skill contracts
2c5050d ♻️ refactor(skills): rename repo skills source dir
f049dfb 📦 deps(skills): drop duplicate first-party superpowers skills
234b335  feat(workflow): add superpowers planning and execution state tracking
c1702a6 📝 docs(markdown): format tracked markdown and drop stale templates
2325409 📝 docs(markdown): clarify optional markdownlint usage
214c44e 🔧 chore(markdown): add markdownlint baseline and lint fixes
a22b324 📝 docs(templates): add execution and memory-bank prompt templates
223a797 📝 docs(templates): update README for Claude Code and current features
4ac8672 📝 docs: simplify README + platform-agnostic tools + auto-create local rules
2431c9d 📝 docs: add claude_md config and use cross-platform paths
d64b248 📝 docs: fix README.md inaccuracies and add Claude Code info
c8d6bf2 🐛 fix(playbook): use relative paths in CLAUDE.md when not at project root
6518f0f  feat(playbook): auto-create CLAUDE.md with path discovery
6ec9a45  feat(skills): add skill_link symlink support + platform-agnostic prompt
9f8b6b5 📝 docs: update README and config example for Claude Code support
79cff6c 📝 docs(skills): add Claude Code platform support
452c6f5  feat(playbook): auto-inject AGENTS.md into CLAUDE.md
e1dbf3c 🐛 fix(skills): remove dual-path from commit-message skill
f3a7259 🔧 chore(ci): use prepare_repo.sh in both workflows
da08212 🔧 chore(ci): extract prepare_repo.sh and clean up workflows
7ade85e 🗑️ remove(tsl): drop syntax_book/, data/ source and build script
f94dba0 ♻️ refactor(skills): update playbook.py and tests for thirdparty/ layout
b3df412 ♻️ refactor(skills): separate thirdparty skills into thirdparty/ subdirectory
64950e7 📦 deps(skills): sync thirdparty skills
a2e3cb0  feat(playbook): add no_backup deploy controls
8609d59 🐛 fix(docs): repair reference catalog source links
956da11 🐛 fix(playbook): publish hidden ci test fixes
3f67754 📦 deps(skills): sync thirdparty skills
08ca87b 📦 deps(skills): add karpathy thirdparty sync
96b705b 📝 docs(tsl): rebuild canonical syntax and routing manual
3ed5052 📦 deps(skills): sync thirdparty skills
60108dd 📦 deps(skills): sync thirdparty skills
da85d4e 🐛 fix(thirdparty): prune nested project snapshots
a2a697e 📦 deps(skills): sync thirdparty skills
9df610a 🐛 fix(thirdparty): exclude duplicated superpowers skills
33dd5bb 🐛 fix(thirdparty): preserve optional manifest fields
91b0ea7 🐛 fix(thirdparty): preserve manifest during snapshot update
2e26f98 🔧 chore(thirdparty): generalize skills sync pipeline
5b9c1e3 📦 deps(skills): sync superpowers
2f2d34a 📝 docs(readme): normalize subtree command spacing
62db7db 🐛 fix(ci): serialize superpowers update and sync
3463223 🐛 fix(ci): use literal superpowers sync paths
48f6de8 📦 deps(skills): sync superpowers
4b23529 🔧 chore(ci): merge superpowers update and sync workflow
a56d75b 📦 deps(skills): sync superpowers
84bcefa 🔧 chore(ci): use ci[bot] commit author name
00a07e5 📦 deps(skills): sync superpowers
7b84daf 🐛 fix(templates): enforce main loop progress tracking
51373d7 🔧 chore(ci): automate superpowers sync workflow
eaaa39c 🐛 fix(ci): prevent stale superpowers sync from restoring skills block
79755c6 📦 deps(skills): sync superpowers
836d878 📦 deps(skills): sync superpowers
8216c9f 📦 deps(skills): sync superpowers
9439505 🐛 fix(playbook): address reported repo issues

git-subtree-dir: docs/standards/playbook
git-subtree-split: 25d895d8b3f56624ccfe99ad7289e9eb49e0f316
2026-05-24 13:04:14 +08:00

302 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Variables And Constants
文档类型:语法主线
是否可直接用于生成代码:是
是否含已验证可执行示例:是
是否含已验证反例:是
遇到不确定时跳转到:[04_values_and_literals.md](04_values_and_literals.md)、[06_functions_and_calls.md](06_functions_and_calls.md)、[12_pitfalls.md](12_pitfalls.md)
手册位置:第 5 篇,共 32 篇。上一篇:[04_values_and_literals.md](04_values_and_literals.md)。下一篇:[06_functions_and_calls.md](06_functions_and_calls.md)。
这一篇收拢变量、常量与两种常量写法。
## 这一篇解决什么问题
回答“普通变量怎样直接使用、`var` 在什么位置出现、常量有哪些基本写法、哪些名字一旦绑定就不能再赋值”。
## 必须记住的规则
- 默认变量模型是“直接赋值即得到变量”,不要求先写 `var`
- 例如:`a := 1; b := array(1, 2, 3);` 这种写法已验证可直接编译。
- `var name;` 目前只能当成一种显式声明写法,不能当成默认必需步骤。
- `const Name = value;``const name := value;` 不能当成完全等价的两种写法。
- 已验证:
- `const Name = value;` 适合函数内部 `const` 段、`unit` 接口常量、类成员常量。
- `const name := value;` 适合顶层直接写的常量,单独成段也能编译。
- 当前已验证:函数内部 `const = expr`、以及松散脚本顶层的 `const = expr` / `const := expr`,都可以把右侧写成常量表达式。
- 这两种常量在当前解释器里都不能再次赋值。
- 当前解释器接受多参数赋值:`[a, b] := array(...)`
- 左侧只有一个变量时,末尾逗号不能省略,必须写成 `[a, ] := array(...)`
- 当左侧变量数大于右侧数组长度时,多出的变量会得到 `nil`
- 右侧数组元素也可以是数组;拆出来的变量会直接得到对应子数组。
- 多参数赋值也可以出现在函数调用参数里。
- 截至 `2026-04-15` 的最小验证里,`{$Explicit+}` 开启后,后续变量必须先用 `var` 声明;未声明变量会报 `variable not defined`
## 已验证语法
默认变量模型:
代码块身份:已验证可执行示例
```tsl
a := 1;
b := array(1, 2, 3);
```
显式 `var` 写法:
代码块身份:已验证可执行示例
```tsl
var a;
a := 1;
```
`{$Explicit+}` 下的显式声明:
代码块身份:已验证可执行示例
```tsl
program test;
begin
{$Explicit+}
var a;
a := 1;
WriteLn(a);
end.
```
顶层最稳的常量写法:
代码块身份:已验证可执行示例
```tsl
const value := 1;
```
顶层 `const :=` 也可以写常量表达式:
代码块身份:已验证可执行示例
```tsl
const value := 1 + 2 * 3;
WriteLn(value);
```
函数内部 `const` 段:
代码块身份:已验证可执行示例
```tsl
function Demo();
const MaxRetries = 1 + 2 * 3;
begin
return MaxRetries;
end;
```
`unit` 接口常量:
代码块身份:已验证可执行示例
```tsl
unit DemoUnit;
interface
const value = 1;
function GetValue();
implementation
function GetValue();
begin
return value;
end;
end.
```
类成员常量:
代码块身份:已验证可执行示例
```tsl
type DemoType = class
const value = 1;
end;
```
顶层 `const =` 只有在“后面继续接可执行语句”的脚本模型里才已验证成立:
代码块身份:已验证可执行示例
```tsl
const MaxRetries = 3 + 4;
value := MaxRetries;
```
代码块身份:已验证可执行示例
```tsl
var a;
a := 1;
```
多参数赋值:
代码块身份:已验证可执行示例
```tsl
[r1, r2] := array(1, 3, 5, 7, 9);
WriteLn(r1);
WriteLn(r2);
```
已验证运行结果:
- 依次输出 `1``3`
单变量拆包时,末尾逗号不能省略:
代码块身份:已验证可执行示例
```tsl
[re, ] := array(1, 2, 3, 4);
WriteLn(re);
```
已验证运行结果:
- 输出 `1`
左侧变量比右侧数组更长时,多出的变量为 `nil`
代码块身份:已验证可执行示例
```tsl
[r1, r2] := array(1);
WriteLn(r1);
WriteLn(r2 = nil);
```
已验证运行结果:
- `r1` 输出 `1`
- `r2 = nil` 输出 `1`
右侧元素也可以是数组:
代码块身份:已验证可执行示例
```tsl
[r1, r2] := array((1, 2), (3, 4));
WriteLn(r1[0]);
WriteLn(r1[1]);
WriteLn(r2[0]);
WriteLn(r2[1]);
```
已验证运行结果:
- 依次输出 `1``2``3``4`
函数返回数组后也可以直接拆包:
代码块身份:已验证可执行示例
```tsl
program test;
function PairAdd(a, b);
begin
return array(0, a + b);
end;
begin
[error, re] := PairAdd(3, 4);
WriteLn(error);
WriteLn(re);
end.
```
已验证运行结果:
- 依次输出 `0``7`
函数参数里也可以使用多参数赋值:
代码块身份:已验证可执行示例
```tsl
program test;
function Test(a, b, c);
begin
return a + b + c;
end;
begin
WriteLn(Test(e := 3, [f, g] := array(1, 2), g));
end.
```
已验证运行结果:
- 输出 `6`
## 最小可编译示例
如果你只是想先落一个可续写的普通变量和顶层常量骨架,用下面这组:
代码块身份:已验证可执行示例
```tsl
const MaxRetries := 3;
counter := MaxRetries;
items := array(1, 2, 3);
```
## 常见误写
- 以为普通变量必须先写 `var` 才能使用。
- 以为 `const =``const :=` 只是初始化方式不同,可以在任何上下文里互换。
- 以为 `const =` 顶层单独写一行就一定成立。
- 以为单变量拆包可以写成 `[a] := array(...)`
- 以为 `{$Explicit+}` 开启后仍然可以继续直接写未声明变量。
代码块身份:反例 / 不可照写
```text
const value := 1;
value := 2;
```
上面这类写法会编译失败,报错点在重新赋值这一行。
代码块身份:反例 / 不可照写
```text
const value = 1;
```
上面这类“顶层单独一行”的 `const =` 在当前解释器里也会编译失败。
代码块身份:反例 / 不可照写
```text
[re] := array(1, 2, 3);
```
上面这种单变量拆包写法在当前解释器里会报 `left side can not be assign to`。单变量时必须写成 `[re, ] := ...`
代码块身份:反例 / 不可照写
```text
program test;
begin
{$Explicit+}
a := 1;
end.
```
上面这类写法在当前解释器里会编译失败,主因是 `variable not defined`
## 跳转指引
- 回看基本类型:见 [04_values_and_literals.md](04_values_and_literals.md)
- 进入表达式:见 [07_expressions_and_operators.md](07_expressions_and_operators.md)
- 看词法和编译选项:见 [18_lexical_structure_and_compile_options.md](18_lexical_structure_and_compile_options.md)
- 看类型与转换:见 [19_types_and_conversions.md](19_types_and_conversions.md)