Files
tsl-devkit/docs/tsl/syntax/32_object_overloads_and_iteration.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.3 KiB
Raw Blame History

Object Overloads And Iteration

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

手册位置:第 32 篇,共 32 篇。上一篇:31_complex_and_weakref.md。这一篇是当前 syntax 深水专题的最后一篇。

这一篇收拢“对象像数组、像容器、像可遍历值”这一组新一代能力:基础算符重载、[] 重载、for in 重载,以及 mrows / mcols / msize 这类矩阵关键字重载。

这一篇解决什么问题

回答“当类不只是普通对象,而要直接参与 obj + xobj[index]for v in objmrows(obj) 这类语言级操作时,当前解释器到底支持哪些真实写法”。

必须记住的规则

  • 对象二元算符重载当前最小可靠形态是成员方法 function operator + (data); 这一类写法。
  • 比较算符当前已验证可写成 function operator < (data, isLeft);,用 isLeft 区分对象在左边还是右边。
  • 对象 [] 读取当前已验证两种写法:function operator[](index);function operator[0](index, s1);
  • 对象 [] 写入当前已验证写法是 function operator[1](index, v);
  • function operator for(flag); 当前已验证可以重载 for in
  • operator for(flag) 里,flag .& 2 可用来区分“一个循环变量”还是“两个循环变量”,flag .& 1 可用来区分“第一次进入”还是“继续迭代”。
  • mrows / mcols / msize 当前已验证可以在类里先声明 function operator mrows(n); 这类签名,再在类外实现 function operator ClassName.mrows(n);
  • 当前已验证可用的是 mrows(obj)mcols(obj)msize(obj) 这类关键字调用,以及 obj.mcols(1) 这类对象方法式调用。
  • function operator++(v);function operator += (v); 当前也已验证可用。
  • 不要把历史资料里的裸 function operator; / function operator1; 或尚未验证的 mcell / mrow / mcol / :: / :. 重载,直接当成当前解释器事实。

已验证语法

二元算符重载

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

program test;
type Tcomplex = class
    vReal;
    vImaginary;
    function operator + (data);
    begin
        r := new Tcomplex();
        if ifnumber(data) then
            r.vReal := vReal + data
        else
        begin
            r.vReal := vReal + data.vReal;
            r.vImaginary := vImaginary + data.vImaginary;
        end;
        return r;
    end;
    function operator < (data, isLeft);
    begin
        if ifnumber(data) then
            v := vReal < data
        else
            v := (vReal ^ 2 + vImaginary ^ 2) < data.vReal ^ 2 + data.vImaginary ^ 2;
        if not isLeft then v := not v;
        return v;
    end;
end;
begin
    t1 := new TComplex();
    t1.vReal := 10;
    t1.vImaginary := 100;
    t2 := t1 + 10;
    WriteLn(t2.vReal);
    WriteLn(t1 < 5);
    WriteLn(t1 < 300);
    WriteLn(5 < t1);
end.

已验证运行结果:

  • 依次输出 20011
  • 说明 obj + value 当前可以通过成员 operator + 接管
  • 说明带 isLeft 的比较算符当前可以同时处理 obj < valuevalue < obj

[] 重载:operator[] / operator[1]

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

program test;
type bb = class
    data;
    function create(v);
    begin
        data := v;
    end;
    function operator[](index);
    begin
        return data[index];
    end;
    function operator[1](index, v);
    begin
        data[index] := v;
    end;
end;
begin
    t := array(1, 2, 3, 4, 5);
    b := new bb(t);
    WriteLn(b[2]);
    b[3] := 999;
    WriteLn(b.data[3]);
end.

已验证运行结果:

  • 依次输出 3999
  • 说明当前解释器下,operator[]operator[1] 可以完成单层下标读取和写入

[] 重载:operator[0] / operator[1]

沿用上一段的 bb 类与测试主体,只把读取签名从 function operator[](index); 改成 function operator[0](index, s1);

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

type bb = class
    // 其余字段、Create()、operator[1] 和测试主体同上一段
    function operator[0](index, s1);
    begin
        return data[index];
    end;
end;

已验证运行结果:

  • 依次输出 3999
  • 说明 operator[0] / operator[1] 这组写法在单层下标场景同样可用

for in 重载

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

program test;
type Box = class
    data;
    findex;
    function create(v);
    begin
        data := v;
    end;
    function operator for(flag);
    begin
        use_pair := flag .& 2;
        again := flag .& 1;
        if not again then
            findex := 0
        else if findex < length(data) - 1 then
            findex++
        else
            return nil;

        if use_pair then
            return array(findex, data[findex]);
        return data[findex];
    end;
end;
begin
    box := new Box(array("A", "B", "C"));
    for v in box do
        WriteLn(v);
    for i, v in box do
        WriteLn(i$":"$v);
end.

已验证运行结果:

  • 单变量循环依次输出 ABC
  • 双变量循环依次输出 0:A1:B2:C
  • 说明 operator for(flag) 当前确实可以重载 for in
  • 也说明同一个对象可以按返回值形态同时支持“单变量遍历”和“索引 + 值遍历”

mrows / mcols / msize 重载

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

program test;
type GridWrap = class
    data;
    function create();
    begin
        data := array(
            ("A": 1, "B": 2, "C": 3),
            ("A": 4, "B": 5, "C": 6)
        );
    end;
    function operator mrows(n);
    function operator mcols(n);
    function operator msize(n);
end;

function operator GridWrap.mrows(n);
begin
    _n := ifnil(n) ? 0 : n;
    return mrows(data, _n);
end;

function operator GridWrap.mcols(n);
begin
    _n := ifnil(n) ? 0 : n;
    return mcols(data, _n);
end;

function operator GridWrap.msize(n);
begin
    _n := ifnil(n) ? 0 : n;
    return msize(data, _n);
end;

begin
    g := new GridWrap();
    WriteLn(mrows(g));
    WriteLn(mcols(g));
    sz := msize(g);
    WriteLn(sz[0]);
    WriteLn(sz[1]);
    cols := g.mcols(1);
    WriteLn(cols[0]);
    WriteLn(cols[1]);
    WriteLn(cols[2]);
end.

已验证运行结果:

  • 依次输出 2323ABC
  • 说明 mrows(obj)mcols(obj)msize(obj) 当前都可由对象重载接管
  • 说明对象方法式调用 obj.mcols(1) 也可继续取得列下标列表

+++=

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

program test;
type bb = class
    data;
    function create(v);
    begin
        data := v;
    end;
    function operator++(v);
    begin
        if v = 0 then
        begin
            r := new bb();
            r.data := data;
            r.data++;
            return r;
        end
        else
            data++;
    end;
    function operator += (v);
    begin
        data += v;
    end;
end;
begin
    b := new bb(10);
    ++b;
    WriteLn(b.data);
    c := b++;
    WriteLn(c.data);
    WriteLn(b.data);
    b += 5;
    WriteLn(b.data);
end.

已验证运行结果:

  • 依次输出 11111217
  • 说明前置 ++ 会直接修改对象状态
  • 说明这个最小样例里,后置 b++ 返回的是递增前快照
  • 说明 operator += (v) 当前可以接管 b += 5

暂不在本页展开的部分

  • :: / :. 遍历重载
  • mcell / mrow / mcol / mIndexCount / mIndex
  • 多级 [] 下标重载
  • 右侧算术如 value + obj
  • 对基础二进制函数的大规模重载族

这些旧资料里都有更深示例,但当前这一篇先只保留已经单独跑通的容器化主干。

跳转指引