Skip to content

集合类型

Targo 有两个集合家族:

  • Go-native 集合:slice<T>map<K, V>Fixed<T, N>chan<T>
  • Runtime-backed 集合:Array<T>Map<K, V>Set<T>

选择正确的类型对语义、人体工学和性能都有影响。

快速选择

场景优先选择
Go 风格动态序列slice<T>
JS 风格方法如 map()filter()Array<T>
Go-native 键值映射map<K, V>
有序 map,带 JS 风格辅助方法Map<K, V>
有序 set,带 JS 风格辅助方法Set<T>
固定大小数组Fixed<T, N>
Goroutine 通信chan<T>

slice<T>

  • Go-native 动态集合
  • 最适合低开销代码和 Go 互操作
  • 使用 slice.makeslice.appendslice.copy
  • 大多数核心逻辑优先使用

Array<T> / T[]

  • Runtime-backed 集合
  • 当你明确需要 pushmapfilterreduce 等方法时使用
  • 支持 Array.of(...)Array.make(...) 构造辅助函数
  • 不要假设 slice<T> 有和 Array<T> 相同的方法面

map<K, V>(Go-native)

  • 映射到 Go map
  • 想要纯 Go map 语义时优先使用
  • 需要 set 语义时用 map<T, bool>

查找模式

当 API 标记为 @comma-ok 时,第一个结果是可能缺失的值,第二个结果是显式存在标志。

typescript
const [value, ok] = users.Get(id);
if (!ok) {
  return [zero<User>(), new Error("user not found")];
}
return [value, null];

Comma-Ok 指南

  • comma-ok 是 Go 风格的"值加存在标志"模式
  • 缺失重要时优先使用显式布尔结果
  • 不要先按 JavaScript undefined 检查建模,再恢复存在信号

Map<K, V>(Runtime-backed)

  • 有序 runtime-backed map,带 JS 风格方法
  • 支持 setgethasdeleteclearsizekeysvaluesforEachentriesfor...of
  • Map.get(key) 返回 V | undefined

Set<T>(Runtime-backed)

  • 有序 runtime-backed set
  • 支持 addhasdeleteclearsizevaluesforEachfor...of

WeakMap<K, V> / WeakSet<T>

  • Runtime-backed 弱引用集合
  • 仅在明确需要弱引用语义时使用

Fixed<T, N>

  • 映射到固定大小 Go 数组
  • 当大小是类型契约的一部分时使用

chan<T>

  • 用于 Go 风格并发
  • go(() => { ... }) 配合使用
  • 通过 switch (chan.$select) 进行 select 风格协调
  • 详细用法见 concurrency.md

实践区分

  • 想要 JS 风格方法面时选 Array<T>Map<K, V>Set<T>
  • 代码主要是 Go 风格且互操作密集时选 slice<T>map<K, V>

常见错误

  • 出于 TypeScript 习惯到处使用 Array<T>,而不是在 Go-native 行为更合适时选 slice<T>
  • 期望 slice<T> 暴露和 Array<T> 相同的方法面
  • 混淆 Go-native map<K, V> 和 runtime-backed Map<K, V>