资讯动态

Wing 语言 Set 集合类型深度指南:标准库 API、可变性语义与 hangar 测试验证

发布时间:2026/10/15 3:47:42 来源:尧图企业网站定制
编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载本文以 Wing 语言标准库Set/MutSet集合类型为核心完整解读其 API 设计、不可变与可变两种语义的差异、集合相等性规则并结合仓库内 10 个测试用例及其 hangar 测试快照展示如何通过模拟器sim平台验证这些行为。读完本文你将能熟练使用 Wing 中的集合类型进行去重存储、成员查询、复制转换与批量测试并理解快照式测试的输出结构。一、从一个测试快照说起在仓库的测试工具链 hangar 中保存着标准库测试的预期输出快照。其中tools/hangar/__snapshots__/test_corpus/sdk_tests/std/set.test.w_test_sim.md记录了set.test.w在 sim模拟器平台下运行wing test的完整 stdoutpass ─ set.test.wsim » root/Default/test:add() pass ─ set.test.wsim » root/Default/test:clear() pass ─ set.test.wsim » root/Default/test:copy() pass ─ set.test.wsim » root/Default/test:copyMut() pass ─ set.test.wsim » root/Default/test:delete() pass ─ set.test.wsim » root/Default/test:equality pass ─ set.test.wsim » root/Default/test:has() pass ─ set.test.wsim » root/Default/test:mutability pass ─ set.test.wsim » root/Default/test:size() pass ─ set.test.wsim » root/Default/test:toArray() Tests 10 passed (10) Snapshots 1 skipped Test Files 1 passed (1) Duration DURATION这份快照表面上是几行测试日志实际上浓缩了 Wing 集合类型的全部核心 APIadd、clear、copy、copyMut、delete、equality、has、mutability、size、toArray。以下逐一展开它们的语言语义、实现原理与测试证据。二、Set 与 MutSet两种可变性语义2.1 语言层面的类型定义在 Wing 语言参考docs/api/05-language-reference.md中集合是六大容器类型之一类型名说明SetTset 类型无序的唯一元素集合默认不可变MutSetT可变 set 类型声明方式为字面量构造let z Setnum[1, 2, 3]; // 不可变 set let zm MutSetnum[1, 2, 3]; // 可变 set核心语义set 跟踪的是唯一值的集合——同一个值只能被加入一次。按官方 by-example 文档docs/by-example/11-sets.md的说明Set 默认不可变SetT需要变更操作时使用MutSetT重复字面量会被自动去重let unqiueNumbers MutSetnum[1, 2, 3, 3, 3]; // 实际仅包含 1、2、3 unqiueNumbers.add(4); unqiueNumbers.delete(1); let uniqueStrings Setstr[unique, values, values]; // 去重后为 [unique, values]2.2 SDK 中的类型实现Set与MutSet在标准库中的实现位于packages/winglang/sdk/src/std/set.ts。文件头注释说明这些类用于为 Wing 提供 JS 原生Set类的 JSII 子集不应当被用户直接消费——用户在 Wing 源码中通过SetT/MutSetT语法使用编译器负责将其映射到 SDK 类型。两个类都声明了私有构造函数private constructor() {}意味着用户代码无法直接new只能通过语言语法构造。每个类都带有_toInflightType()静态方法通过InflightClient.forType()生成 inflight 运行时类型保证集合类型在 preflight 与 inflight 两个阶段都能被序列化与使用。2.3 API 总览依据 SDK 源码与 API 参考docs/api/04-standard-library/std/set.md两个类型对外暴露的成员如下SetT不可变成员签名说明sizenum属性集合长度has(value)bool判断元素是否存在toArray()Array生成与集合内容一致的不可变数组copyMut()MutSet生成内容相同的可变集合MutSetT可变成员签名说明sizenum属性集合长度has(value)bool判断元素是否存在add(value)MutSet向集合添加值delete(value)bool从集合移除值若值原本存在返回true否则返回falseclear()void清空集合所有元素copy()Set生成内容相同的不可变集合toArray()Array生成与集合内容一致的不可变数组注意add的返回值类型被声明为MutSet便于链式调用而delete返回布尔值标记是否真的删除了元素。2.4 宏替换的实现细节在packages/winglang/sdk/src/std/set.ts中copyMut、toArray、copy三个方法体都只是throw new Error(Macro)真正的实现由macro注解在编译期展开copyMut()标注为macro new Set($self$)——编译为用原集合内容构造一个新的SettoArray()标注为macro [...($self$)]——编译为数组展开语法生成与原集合等价的数组MutSet.copy()同样标注为macro new Set($self$)——把可变集合拷贝为不可变Set。其余方法size、has、add、delete、clear则是抽象占位throw new Error(Abstract)由编译器生成的运行时 JS 代码提供真实行为与 JS 原生Set的语义保持一致。这是 Wing“统一 preflight/inflight 模型”在容器类型上的体现同一套 API 在两个阶段行为一致。三、10 个测试用例逐项剖析测试源码位于tests/sdk_tests/std/set.test.w它同时包含顶层直接执行的断言文件加载时即运行与 10 个test块由测试框架调度执行。快照中列出的正是这 10 个 test 块。3.1toArray()集合转数组let mySet Setnum [1, 2, 3]; let myArrayFromSet mySet.toArray(); assert(myArrayFromSet.at(0) 1); assert(myArrayFromSet.length mySet.size); assert(myArrayFromSet.length 3);覆盖场景包括普通不可变Setnum转数组逐下标断言元素MutSetstr转数组空集合Setbool[]转空数组Arraybool[]元素本身是数组的集合MutSetArraystr集合元素可以是任意类型包括容器类型。这验证了toArray()的“浅拷贝不可变数组”语义数组内容与原集合一致且数组长度恒等于集合的size。3.2equality可变性不影响相等性test equality{ assert(Setnum[1, 2] MutSetnum[1, 2]); assert(Setbool[true, false] MutSetbool[false, true]); }这里直接对应语言参考docs/api/05-language-reference.md第 6.1.2 节“集合类型”的相等性规则两个集合相等当且仅当元素个数相同且每个元素按各自类型的相等规则一一对应元素顺序只在Array/MutArray中有意义集合是无序的集合的可变性不影响相等性——MutArray可等于内容相同的Array同理MutSet可等于内容相同的Set只有同一种容器“种类”才能比较相等Array 不能等于 MapSet 不能与 Array 比较。测试中Setbool[true, false] MutSetbool[false, true]还额外验证了集合的无序性元素顺序不同但内容相同依然相等。3.3mutability可变集合的完整操作链test mutability { let openings MutSetstr [A Cruel Angels Thesis, Lilium, Unravel, TOP]; let immutOpenings: Setstr openings.copy(); // 可变 → 不可变 assert(immutOpenings.copyMut() openings); // 不可变 → 可变内容仍相等 openings.add(Abnormalize); assert(openings.has(Abnormalize)); // 新增可查 openings.delete(TOP); assert(openings.has(TOP) false); // 删除后不可查 openings.clear(); assert(openings.size 0); // 清空后大小为 0 }这个用例把copy、copyMut、add、has、delete、clear、size串成一条完整的状态转换链路验证了可变与不可变集合之间可以互相拷贝转换且转换前后内容相等。3.4size()长度统计test size() { let maleVA Setstr [Kenjiro Tsuda, Akira Ishida, Yoshitsugu Matsuoka]; assert(maleVA.size 3); let femaleVA MutSetstr[Saori Hayami, Miyuki Sawashiro]; assert(femaleVA.size 2); femaleVA.add(Maaya Sakamoto); assert(femaleVA.size 3); // 添加后 size 增加 femaleVA.clear(); assert(femaleVA.size 0); // 清空后 size 归零 }同时验证不可变集合与可变集合的size属性以及add/clear对 size 的联动影响。3.5has()成员存在性查询test has() { let genre Setstr [isekai, mecha, cyberpunk]; assert(genre.has(drama) false); assert(genre.has(mecha)); let mutGenre MutSetstr [rom-com, sports, sci-fi]; mutGenre.delete(rom-com); mutGenre.add(psychological); assert(mutGenre.has(psychological)); assert(mutGenre.has(rom-com) false); }验证has对存在元素返回true、对不存在元素返回false且删除后立即不可查、新增后立即可查。3.6copyMut()不可变集合 → 可变集合test copyMut() { let talkingQuirks Setstr [dattebane, battebayo, dattebasa]; assert(talkingQuirks.copyMut() MutSetstr [dattebane, battebayo, dattebasa]); }验证Set上唯一的“转可变”入口copyMut()产出的MutSet与原Set内容相等再次印证可变性不影响相等性。3.7add()添加元素test add() { let evaRebuild MutSetnum [1.11, 2.22, 3.33]; evaRebuild.add(3.01.0); // 数值表达式作为元素 assert(evaRebuild.has(3.01.0)); assert(evaRebuild MutSetnum[1.11, 2.22, 3.33, 3.01.0]); }值得注意的两点一是集合元素可以是任意表达式这里是用3.01.0计算出的num二是add之后与字面量集合直接比较相等。3.8delete()删除元素及其返回值test delete() { let studios MutSetstr [Gainax, Ghibli, Production I.G., Shaft]; assert(studios.delete(Gainax)); // 删除已存在元素 → true assert(studios.has(Gainax) false); assert(studios.delete(Sunrise) false); // 删除不存在元素 → false assert(studios.size 3); }精确验证delete的布尔返回值语义目标值原本在集合中返回true否则返回false与 JSSet.prototype.delete一致。3.9clear()清空集合test clear() { let demographics MutSetstr [shounen, shoujo, josei, seinen]; demographics.clear(); assert(demographics.size 0); demographics.add(kodomo); demographics.clear(); // 再次清空 assert(demographics.has(kodomo) false); }验证clear()幂等且彻底清空后size 0重新添加后再清空元素同样不可查。3.10copy()可变集合 → 不可变集合test copy() { let acronyms MutSetMapstr [{SEL Serial Experiments Lain, NGE Neon Genesis Evangelion}]; let copyAcronyms acronyms.copy(); assert(copyAcronyms SetMapstr[{SEL Serial Experiments Lain, NGE Neon Genesis Evangelion}]); acronyms.add({DomeKano Domestic na Kanojo}); let copyAcronymsNew acronyms.copy().copyMut(); // 链式拷贝 assert(copyAcronymsNew acronyms); }验证两点copy()产出不可变Set且内容与原MutSet相等copy().copyMut()链式转换后依然与原集合相等。同时该用例使用了MutSetMapstr证明集合元素可以是复杂容器如Map并且深度嵌套内容也能参与相等比较。四、快照是如何生成的hangar 测试框架要理解快照文件本身需要了解 Wing 的 E2E 测试工具 hangar位于tools/hangar。它对tests/sdk_tests、tests/valid、tests/doc_examples等目录下的每个.w文件自动生成测试用例并执行4.1 测试用例的自动生成tools/hangar/src/generate_tests.ts递归扫描源目录中的.w文件为每个文件生成两类 vitest 用例wing compile -t tf-aws编译为 Terraform AWS 目标产出set.test.w_compile_tf-aws.md这类编译快照wing test -t sim在模拟器平台运行测试产出_test_sim.md这类运行快照。4.2 测试执行的实现tools/hangar/src/generated_test_targets.ts中的testTest()负责运行wing test -t sim只有入口文件.test.w、main.w等才会真正执行测试把 stdout/stderr 写入fileMap再调用createMarkdownSnapshot落盘为 Markdown 快照。这就是set.test.w_test_sim.md里stdout.log区块的来源。4.3 快照内容为何如此“干净”注意快照中的Duration DURATION——这不是神秘占位符而是tools/hangar/src/utils.ts中sanitizeOutput()的规范化处理为了让快照在不同机器上稳定复现它会把测试耗时Duration \dm[\d.]s、时间戳、绝对路径、端口号、IP 等环境相关输出统一替换为DURATION、TIMESTAMP、ABSOLUTE、PORT等占位符。这也是快照工程中消除非确定性输出的标准做法。同时set.test.w编译到 tf-aws 平台时没有任何云资源纯计算逻辑所以对应的编译快照只有最小化的main.tf.json仅含awsprovider 声明——这从侧面说明 Set 是纯语言层面的容器类型编译时不会产生基础设施资源。五、如何运行这些测试仓库中该测试可通过 hangar 生成的目标执行由package.json/turbo.json编排核心命令为# 在 hangar 包内运行 sdk_tests 相关的 sim 测试实际命令以仓库脚本为准 wing test -t sim tests/sdk_tests/std/set.test.w手动验证集合行为最简单的方式是像 by-example 文档那样编写一个main.w然后用 Wing 控制台或模拟器运行wing it # 本地运行 Wing 控制台 # 或 wing test -t sim main.w在docs/by-example/11-sets.md的示例中MutSet的toArray()与size会分别输出[2,3,4]和3印证了 add/delete 后集合状态的变化。六、实用要点总结默认不可变按需可变SetT用于只读场景需要增删时显式使用MutSetT这符合 Wing 容器类型“immutable by default”的设计原则。四个转换/读取成员toArray()转数组、copy()变不可变、copyMut()变可变、has()查询在两类集合上按需提供均通过macro在编译期展开为 JS 原生操作。相等性不看可变性与顺序Setnum[1, 2] MutSetnum[1, 2]成立Setnum[1, 2, 3] Setnum[3, 2, 1]也成立这是语言参考第 6.1.2 节明确规定的集合语义。delete有返回值返回true表示确实删除了元素false表示值本就不存在可用于防御式编程。测试快照即文档set.test.w_test_sim.md与set.test.w组合起来就是 Set 全部 API 的可执行规格说明——10 个用例覆盖了所有成员与关键边界空集合、嵌套容器元素、链式拷贝、幂等清空等。如果需要进一步研究 API 的完整签名与参数类型可查阅docs/api/04-standard-library/std/set.md想深入了解相等性规则在集合上的应用可阅读docs/api/05-language-reference.md第 6.1.2 节。赞分享编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载相关推荐Wing 语言 math 标准库 factorial 函数深度解析从 SDK 实现到 Hangar 快照测试验证Wing 语言 math 标准库 factorial 函数深度解析从 SDK 实现到 Hangar 快照测试验证 math.factorial 是 Wing编程语言编译器云原生语言运行时Wing 语言 expect 标准库断言 API 全解析从 hangar 快照看编译产物与测试验证Wing 语言 expect 标准库断言 API 全解析从 hangar 快照看编译产物与测试验证 本文围绕 Wing 开源仓库中的 expect 标准库模块编程语言编译器云原生语言运行时Wing 云编程语言 fs 标准库 JSON 文件读写与 Hangar 快照测试验证Wing 云编程语言 fs 标准库 JSON 文件读写与 Hangar 快照测试验证 Wing 是一门面向云的编程语言它的标准库 fs 模块提供了在 pref编程语言编译器云原生语言运行时上一篇Diem 交易手续费模块深度解析TransactionFee 的初始化、累积与链上销毁机制下一篇深入解析 TanStack Table v9 的 RowModelFns\_FeatureMap排序、过滤与聚合函数注册表的类型中枢创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑