Files
tsl-devkit/docs/tsl/syntax/31_complex_and_weakref.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

329 lines
8.1 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.
# Complex And WeakRef
文档类型:语法主线
是否可直接用于生成代码:仅部分
是否含已验证可执行示例:是
是否含已验证反例:是
遇到不确定时跳转到:[09_objects_and_classes.md](09_objects_and_classes.md)、[32_object_overloads_and_iteration.md](32_object_overloads_and_iteration.md)、[12_pitfalls.md](12_pitfalls.md)
手册位置:第 31 篇,共 32 篇。上一篇:[30_runtime_services_and_global_cache.md](30_runtime_services_and_global_cache.md)。下一篇:[32_object_overloads_and_iteration.md](32_object_overloads_and_iteration.md)。
这一篇只讲当前解释器下已经实际跑通的两组新一代语言能力:复数,以及弱引用 / 自动弱引用里当前真正可靠的最小写法。
## 这一篇解决什么问题
回答“复数现在到底怎样写,弱引用到底有哪些语法真的能用,哪些历史资料里的写法今天不能直接照抄”。
## 必须记住的规则
- 复数字面量可以直接写成 `a + bj`,也可以用 `complex(a, b)` 构造。
- `datatype(z)` 对复数返回 `41``ifcomplex(z)` 对复数返回 `1`
- `real``imag``conj``abs` 当前都已验证可用。
- 当前解释器里,实数 `x` 与复数 `x + 0j` 的相等比较结果为真。
- `complex(array(...), imag)` 会返回 `Array``complex(fmarray..., imag)` 会返回 `FMArray`,并且其单元格类型是 `41`
- 弱引用能力的条件编译宏当前已验证是 `weakptr`;自动弱引用相关宏是 `AutoWeak`
- `weakref(obj)` 可以创建弱引用;对象仍存活时,`weakref_get(w)` 可以拿回强引用。
- `checkweakref(w)` 当前已验证:对象仍存活时返回 `1`,对象已释放后返回 `-1`
- 对已经失效的弱引用直接调用 `weakref_get(w)`,当前解释器里会运行报错,不要把它当成“安全返回 nil”的接口。
- 类成员上的 `[WeakRef] field;``[AutoRef] field;` 当前已验证可以通过。
- `[WeakRef]` 成员不会阻止对象析构;强引用释放后,对象会正常销毁。
- 历史资料里的类内段落式 `WeakRef;` / `AutoRef;` 在当前解释器里没有通过,错误信息包含 `invalid class definition`
## 已验证语法
### 复数常量、类型与基础读取
代码块身份:已验证可执行示例
```tsl
program test;
begin
z1 := 4 + 3j;
z2 := complex(5, -2);
WriteLn(datatype(z1));
WriteLn(ifcomplex(z1));
WriteLn(real(z1));
WriteLn(imag(z1));
WriteLn(z2);
end.
```
已验证运行结果:
- `datatype(4 + 3j)` 返回 `41`
- `ifcomplex(4 + 3j)` 返回 `1`
- `real(4 + 3j)` 返回 `4`
- `imag(4 + 3j)` 返回 `3`
- `complex(5, -2)` 打印结果是 `5-2j`
### 共轭、模与等值比较
代码块身份:已验证可执行示例
```tsl
program test;
begin
z := 4 + 3j;
c := conj(z);
WriteLn(abs(z));
WriteLn(real(c));
WriteLn(imag(c));
if 3.15 = 3.15 + 0j then
WriteLn(1);
else
WriteLn(0);
end.
```
已验证运行结果:
- `abs(4 + 3j)` 返回 `5`
- `conj(4 + 3j)` 的实部是 `4`、虚部是 `-3`
- `3.15 = 3.15 + 0j` 当前比较结果为真
### 复数 `Array` 与复数 `FMArray`
代码块身份:已验证可执行示例
```tsl
program test;
begin
a := complex(array(1, 2, 3), 5.5);
f := complex(fmarray[1, 2, 3], 5.5);
WriteLn(datatype(a));
WriteLn(length(a));
WriteLn(a[0], ',', a[1], ',', a[2]);
WriteLn(datatype(f));
WriteLn(datatype(f, 1));
WriteLn(length(f));
WriteLn(f[0], ',', f[1], ',', f[2]);
end.
```
已验证运行结果:
- `complex(array(1, 2, 3), 5.5)``datatype``5`
- 上述复数数组长度是 `3`,三个元素依次是 `1+5.5j``2+5.5j``3+5.5j`
- `complex(fmarray[1, 2, 3], 5.5)``datatype``27`
- 上述复数 `FMArray` 的单元格类型 `datatype(f, 1)``41`
-`FMArray` 长度是 `3`,三个元素依次是 `1+5.5j``2+5.5j``3+5.5j`
### 弱引用能力的条件编译判定
代码块身份:已验证可执行示例
```tsl
program test;
begin
{$IFDEF weakptr}
WriteLn('weakptr');
{$ELSE}
WriteLn('Noweakptr');
{$ENDIF}
{$IFDEF AutoWeak}
WriteLn('AutoWeak');
{$ELSE}
WriteLn('NoAutoWeak');
{$ENDIF}
end.
```
已验证运行结果:
- 当前解释器会输出 `weakptr`
- 当前解释器也会输出 `AutoWeak`
- 说明这代解释器里,弱引用能力的条件编译开关应写成 `weakptr`,自动弱引用能力的开关应写成 `AutoWeak`
### `weakref`、`weakref_get` 与 `checkweakref`
对象仍然存活时:
代码块身份:已验证可执行示例
```tsl
program test;
type TNode = class
name;
function create(v);
begin
name := v;
end;
end;
begin
a := new TNode('A');
w := weakref(a);
WriteLn(checkweakref(w));
s := weakref_get(w);
WriteLn(s.name);
end.
```
已验证运行结果:
- `checkweakref(w)` 返回 `1`
- `weakref_get(w)` 能拿回强引用
- 通过拿回的强引用可继续访问对象成员,此处输出 `A`
沿用同一个 `TNode`,只把主体改成下面这样:
代码块身份:配置片段 / 概念骨架
```tsl
program test;
begin
a := new TNode('A');
w := weakref(a);
WriteLn(checkweakref(w));
a := nil;
WriteLn(checkweakref(w));
end.
```
已验证运行结果:
- 创建后 `checkweakref(w)` 返回 `1`
- 把最后一个强引用设为 `nil` 后,`checkweakref(w)` 返回 `-1`
当前还额外验证到:
代码块身份:反例 / 不可照写
```text
a := new TNode('A');
w := weakref(a);
a := nil;
t := weakref_get(w);
```
上面这种写法在当前解释器里会运行报错,因此访问弱引用前应先做 `checkweakref(w)` 判定。
### `[WeakRef]` 与 `[AutoRef]` 成员标记
成员级标记当前可以直接写在类里:
代码块身份:已验证可执行示例
```tsl
program test;
type TChild = class
public
[WeakRef] owner1;
[AutoRef] owner2;
end;
begin
WriteLn(1);
end.
```
已验证运行结果:
- 上述写法可以正常执行,并输出 `1`
- 说明 `[WeakRef] field;``[AutoRef] field;` 当前都能通过
`[WeakRef]` 成员不会阻止对象析构:
代码块身份:已验证可执行示例
```tsl
program test;
type TA = class
public
function destroy();
begin
WriteLn('Destroy');
end;
end;
type TB = class
public
[WeakRef] owner;
function Bind(v);
begin
owner := v;
end;
end;
begin
a := new TA();
b := new TB();
b.Bind(a);
a := nil;
WriteLn('AfterNil');
end.
```
已验证运行结果:
- 输出顺序是 `Destroy``AfterNil`
- 说明 `TB.owner` 作为 `[WeakRef]` 成员,不会把 `TA` 实例继续强持有
## 暂不在本页展开的部分
- 复数统计函数、分解函数与更大函数族
- `MakeWeakRef``MakeStrongRef``weakref_check` 等别名接口
- `property write` 传播自动弱引用的更复杂规则
- 循环引用场景里的完整模式化写法
## 最小可编译示例
复数最短骨架:
代码块身份:已验证可执行示例
```tsl
program test;
begin
z := 4 + 3j;
WriteLn(real(z));
WriteLn(imag(z));
end.
```
弱引用最短骨架:
代码块身份:已验证可执行示例
```tsl
program test;
type TNode = class
name;
function create(v);
begin
name := v;
end;
end;
begin
a := new TNode('A');
w := weakref(a);
WriteLn(checkweakref(w));
end.
```
## 常见误写
- 把弱引用能力的条件编译宏写成 `WeakRef`
- 以为 `weakref_get(deadWeakRef)` 会像普通可空访问那样安全返回 `nil`
- 以为历史资料里的类内段落式 `WeakRef;` / `AutoRef;` 现在也能直接通过。
- 以为 `[WeakRef]` 成员会继续强持有对象。
代码块身份:反例 / 不可照写
```text
type TChild = class
public
owner0;
[WeakRef] owner1;
WeakRef;
owner2;
AutoRef;
owner3;
end;
```
上面这种把 `WeakRef;` / `AutoRef;` 当作类内段落切换的写法,在当前解释器里会编译失败,错误信息包含 `invalid class definition`
## 跳转指引
- 回看语法主入口:见 [index.md](index.md)
- 回看对象主线:见 [09_objects_and_classes.md](09_objects_and_classes.md)
- 看对象重载:见 [32_object_overloads_and_iteration.md](32_object_overloads_and_iteration.md)