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
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
# Object Overloads And Iteration
|
||||
|
||||
文档类型:语法主线
|
||||
是否可直接用于生成代码:仅部分
|
||||
是否含已验证可执行示例:是
|
||||
是否含已验证反例:否
|
||||
遇到不确定时跳转到:[09_objects_and_classes.md](09_objects_and_classes.md)、[23_object_runtime_and_introspection.md](23_object_runtime_and_introspection.md)、[31_complex_and_weakref.md](31_complex_and_weakref.md)
|
||||
|
||||
手册位置:第 32 篇,共 32 篇。上一篇:[31_complex_and_weakref.md](31_complex_and_weakref.md)。这一篇是当前 syntax 深水专题的最后一篇。
|
||||
|
||||
这一篇收拢“对象像数组、像容器、像可遍历值”这一组新一代能力:基础算符重载、`[]` 重载、`for in` 重载,以及 `mrows` / `mcols` / `msize` 这类矩阵关键字重载。
|
||||
|
||||
## 这一篇解决什么问题
|
||||
|
||||
回答“当类不只是普通对象,而要直接参与 `obj + x`、`obj[index]`、`for v in obj`、`mrows(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` / `::` / `:.` 重载,直接当成当前解释器事实。
|
||||
|
||||
## 已验证语法
|
||||
|
||||
### 二元算符重载
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
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.
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
|
||||
- 依次输出 `20`、`0`、`1`、`1`
|
||||
- 说明 `obj + value` 当前可以通过成员 `operator +` 接管
|
||||
- 说明带 `isLeft` 的比较算符当前可以同时处理 `obj < value` 和 `value < obj`
|
||||
|
||||
### `[]` 重载:`operator[]` / `operator[1]`
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
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.
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
|
||||
- 依次输出 `3`、`999`
|
||||
- 说明当前解释器下,`operator[]` 和 `operator[1]` 可以完成单层下标读取和写入
|
||||
|
||||
### `[]` 重载:`operator[0]` / `operator[1]`
|
||||
|
||||
沿用上一段的 `bb` 类与测试主体,只把读取签名从 `function operator[](index);` 改成 `function operator[0](index, s1);`:
|
||||
|
||||
代码块身份:配置片段 / 概念骨架
|
||||
|
||||
```tsl
|
||||
type bb = class
|
||||
// 其余字段、Create()、operator[1] 和测试主体同上一段
|
||||
function operator[0](index, s1);
|
||||
begin
|
||||
return data[index];
|
||||
end;
|
||||
end;
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
|
||||
- 依次输出 `3`、`999`
|
||||
- 说明 `operator[0]` / `operator[1]` 这组写法在单层下标场景同样可用
|
||||
|
||||
### `for in` 重载
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
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.
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
|
||||
- 单变量循环依次输出 `A`、`B`、`C`
|
||||
- 双变量循环依次输出 `0:A`、`1:B`、`2:C`
|
||||
- 说明 `operator for(flag)` 当前确实可以重载 `for in`
|
||||
- 也说明同一个对象可以按返回值形态同时支持“单变量遍历”和“索引 + 值遍历”
|
||||
|
||||
### `mrows` / `mcols` / `msize` 重载
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
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.
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
|
||||
- 依次输出 `2`、`3`、`2`、`3`、`A`、`B`、`C`
|
||||
- 说明 `mrows(obj)`、`mcols(obj)`、`msize(obj)` 当前都可由对象重载接管
|
||||
- 说明对象方法式调用 `obj.mcols(1)` 也可继续取得列下标列表
|
||||
|
||||
### `++` 与 `+=`
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
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.
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
|
||||
- 依次输出 `11`、`11`、`12`、`17`
|
||||
- 说明前置 `++` 会直接修改对象状态
|
||||
- 说明这个最小样例里,后置 `b++` 返回的是递增前快照
|
||||
- 说明 `operator += (v)` 当前可以接管 `b += 5`
|
||||
|
||||
## 暂不在本页展开的部分
|
||||
|
||||
- `::` / `:.` 遍历重载
|
||||
- `mcell` / `mrow` / `mcol` / `mIndexCount` / `mIndex`
|
||||
- 多级 `[]` 下标重载
|
||||
- 右侧算术如 `value + obj`
|
||||
- 对基础二进制函数的大规模重载族
|
||||
|
||||
这些旧资料里都有更深示例,但当前这一篇先只保留已经单独跑通的容器化主干。
|
||||
|
||||
## 跳转指引
|
||||
|
||||
- 回看对象模型:见 [09_objects_and_classes.md](09_objects_and_classes.md)
|
||||
- 回看语法主入口:见 [index.md](index.md)
|
||||
- 回看对象运行时反射:见 [23_object_runtime_and_introspection.md](23_object_runtime_and_introspection.md)
|
||||
- 回看复数与弱引用:见 [31_complex_and_weakref.md](31_complex_and_weakref.md)
|
||||
Reference in New Issue
Block a user