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

8.1 KiB
Raw Blame History

Complex And WeakRef

文档类型:语法主线 是否可直接用于生成代码:仅部分 是否含已验证可执行示例:是 是否含已验证反例:是 遇到不确定时跳转到:09_objects_and_classes.md32_object_overloads_and_iteration.md12_pitfalls.md

手册位置:第 31 篇,共 32 篇。上一篇:30_runtime_services_and_global_cache.md。下一篇:32_object_overloads_and_iteration.md

这一篇只讲当前解释器下已经实际跑通的两组新一代语言能力:复数,以及弱引用 / 自动弱引用里当前真正可靠的最小写法。

这一篇解决什么问题

回答“复数现在到底怎样写,弱引用到底有哪些语法真的能用,哪些历史资料里的写法今天不能直接照抄”。

必须记住的规则

  • 复数字面量可以直接写成 a + bj,也可以用 complex(a, b) 构造。
  • datatype(z) 对复数返回 41ifcomplex(z) 对复数返回 1
  • realimagconjabs 当前都已验证可用。
  • 当前解释器里,实数 x 与复数 x + 0j 的相等比较结果为真。
  • complex(array(...), imag) 会返回 Arraycomplex(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

已验证语法

复数常量、类型与基础读取

代码块身份:已验证可执行示例

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

共轭、模与等值比较

代码块身份:已验证可执行示例

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

代码块身份:已验证可执行示例

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)datatype5
  • 上述复数数组长度是 3,三个元素依次是 1+5.5j2+5.5j3+5.5j
  • complex(fmarray[1, 2, 3], 5.5)datatype27
  • 上述复数 FMArray 的单元格类型 datatype(f, 1)41
  • FMArray 长度是 3,三个元素依次是 1+5.5j2+5.5j3+5.5j

弱引用能力的条件编译判定

代码块身份:已验证可执行示例

program test;
begin
{$IFDEF weakptr}
    WriteLn('weakptr');
{$ELSE}
    WriteLn('Noweakptr');
{$ENDIF}
{$IFDEF AutoWeak}
    WriteLn('AutoWeak');
{$ELSE}
    WriteLn('NoAutoWeak');
{$ENDIF}
end.

已验证运行结果:

  • 当前解释器会输出 weakptr
  • 当前解释器也会输出 AutoWeak
  • 说明这代解释器里,弱引用能力的条件编译开关应写成 weakptr,自动弱引用能力的开关应写成 AutoWeak

weakrefweakref_getcheckweakref

对象仍然存活时:

代码块身份:已验证可执行示例

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,只把主体改成下面这样:

代码块身份:配置片段 / 概念骨架

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

当前还额外验证到:

代码块身份:反例 / 不可照写

a := new TNode('A');
w := weakref(a);
a := nil;
t := weakref_get(w);

上面这种写法在当前解释器里会运行报错,因此访问弱引用前应先做 checkweakref(w) 判定。

[WeakRef][AutoRef] 成员标记

成员级标记当前可以直接写在类里:

代码块身份:已验证可执行示例

program test;
type TChild = class
public
    [WeakRef] owner1;
    [AutoRef] owner2;
end;
begin
    WriteLn(1);
end.

已验证运行结果:

  • 上述写法可以正常执行,并输出 1
  • 说明 [WeakRef] field;[AutoRef] field; 当前都能通过

[WeakRef] 成员不会阻止对象析构:

代码块身份:已验证可执行示例

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.

已验证运行结果:

  • 输出顺序是 DestroyAfterNil
  • 说明 TB.owner 作为 [WeakRef] 成员,不会把 TA 实例继续强持有

暂不在本页展开的部分

  • 复数统计函数、分解函数与更大函数族
  • MakeWeakRefMakeStrongRefweakref_check 等别名接口
  • property write 传播自动弱引用的更复杂规则
  • 循环引用场景里的完整模式化写法

最小可编译示例

复数最短骨架:

代码块身份:已验证可执行示例

program test;
begin
    z := 4 + 3j;
    WriteLn(real(z));
    WriteLn(imag(z));
end.

弱引用最短骨架:

代码块身份:已验证可执行示例

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] 成员会继续强持有对象。

代码块身份:反例 / 不可照写

type TChild = class
public
    owner0;
    [WeakRef] owner1;
    WeakRef;
    owner2;
    AutoRef;
    owner3;
end;

上面这种把 WeakRef; / AutoRef; 当作类内段落切换的写法,在当前解释器里会编译失败,错误信息包含 invalid class definition

跳转指引