这是一组 Kotlin 小工具,包含四个辅助函数,每个函数都配有一段关于“它会在哪里误导你”的说明。原文强调:这些函数小到可以凭记忆写出来,也正因如此,一旦写进代码就很少有人再回头审查。
一、对称差集(symmetricDifference) 以中缀函数形式为 Collection 提供 symmetricDifference(other),通过“左侧减去对方”和“右侧减去自己”再取并集,返回只出现在恰好一侧的元素。典型用途是:在把本地存储的 id 列表与新获取的 id 列表进行对账时,一次性得到新增和删除两类结果。 局限:这是集合运算,只能回答成员关系。重复元素会被合并,顺序会丢失;仅仅移动了位置的元素在两侧都存在,因此会被报告为未变更。若对模型对象而非 id 运算,结果取决于模型的 equals;对 data class 而言,equals 覆盖所有字段,因此只改标题也会让该条目同时被报告为删除和新增。建议先对 id 做差集,再单独比较匹配到的对象内容。
二、位置索引(indexMap) 为 Iterable 提供 indexMap(),用 forEachIndexed 把元素映射到其下标,返回 Map。它可以把循环内反复调用 indexOf 的扫描改为一次遍历加常数时间查找,常用于按另一个列表的顺序对某个列表排序。 局限:赋值是无条件的,因此最后出现的元素获胜;重复元素会映射到最终位置,返回的 map 比列表短,而且不会报错。它适用于元素唯一的 id 列表,不适用于其他情况;若想保留首次出现位置,应改用 getOrPut。键类型同样受 equals 影响。
三、时间戳文本的容错解析与序列化 针对 MM:SS.mm 单词 MM:SS.mm 单词…… 这类载荷,用正则只匹配时间戳,再按相邻时间戳的位置切出中间文本。原文给出完整示例代码:用 destructured 取出分、秒、小数部分;小数位数决定单位,两位表示百分之一秒,因此两位时要乘 10;每个数字字段在解析失败时回退为 0;若结果为空则返回 null,让调用方回退到更粗粒度的格式。 序列化函数应与解析函数放在一起,并把解析时去掉的内容补回来:行级解析会去掉行时间戳后的空格,写入时需要重新补上该分隔符,并在格式标记不匹配时拒绝写入。 局限有三点:前两点是静默的。第一,用单个正则同时匹配时间戳和文本,会把文本的形态绑定到该模式上,标点、另一个尖括号、字符类未考虑的字符脚本都会被丢弃,载荷看起来只是变短了;改为切片到下一个分隔符则不对文本形态作任何假设。第二,小数部分的数字位数就是单位,若不检查长度直接按数字读取,两位时间戳会落到应有值的十分之一,而且偏差早期看起来很像调参问题而不是解析问题。第三,各数字字段都回退而非报错,使“无法解析”与“零”成为同一个答案;这本身可以接受,但整体载荷失败应保持为 null,让调用方改用更粗的渲染,而不是丢掉整个屏幕。此外,每个切片上的 trim() 没有人负责恢复,只有在 token 仅作为渲染期值时才安全;若把解析后的列表再序列化回文本,单词会连在一起,因此序列化处也要补回分隔符,并始终按格式标记做保护。
四、外部链接转深链接(toAppDeepLinkOrNull) toAppDeepLinkOrNull() 对字符串做 trim,先拒绝非 http:// 或 https:// 前缀,再尝试 Uri.parse,失败则返回 null;然后取主机名,转小写并去掉开头的 www.,继续匹配后重写为自有 scheme(示例为 yourapp://watch?v=$id),交给已有的深链接处理入口。 原文的核心建议是:不要试图“处理”外部链接,而要“翻译”它。现有深链接处理器已经知道各种特殊情况(哪些 id 前缀对应哪类集合、哪些需要加前缀),另写一个处理器起初像复制品,等规则变化时就会逐渐偏离。把 URL 重写为自有 scheme 并交给同一个入口,规则就只有一套。四个细节让转换可信:解析前先拒绝非 http(s) 文本;对不支持的内容返回 null,使无法处理的粘贴链接退化为搜索而非失败;匹配前规范化主机名(转小写、去掉开头的 www.),否则同一链接会因复制来源不同而时灵时不灵;对同时携带条目和集合的歧义情况在此处一次性决定,避免各调用方各自猜测。
五、验证方法 原文给出用 grep 检查的步骤:解析入口应只有一种失败模式即返回 null,用 grep 检索 return null、throw、!!、require(、checkNotNull(,通过条件是所有命中都是 return null,不出现 throw、!!、require( 或 checkNotNull(;再用 grep 确认文件正确(时间戳正则与小数长度单位检查都应打印)。对可能返回 null 的转换函数,每个调用方都要说明 null 的含义。两个集合辅助函数只对不重复元素正确,应检查传入的接收者是否持有 id 而非模型对象、是否可能重复;完全没有调用点的工具,本身也是一项发现——没人调用的工具就没人验证过。
适用场景:Kotlin 项目中的共享模块、需要比对 id 集合的数据同步、按另一列表排序、时间戳文本解析与回写、以及把外部 http(s) 链接接入应用内深链接的场景。限制:以上说明均针对元素唯一性、equals 语义、小数位数、trim 分隔符及链接歧义等前提;原文未提供该工具集的安装方式、依赖坐标、授权协议或发布状态,暂未提供。