该技能描述 KMP 多平台 UI 构建中的一个编译期陷阱及其处置方式。
用途 多平台 UI 构建通常有两个供应方提供同一 UI 工具包:平台厂商的产物只存在于平台目标,多平台厂商的移植版覆盖全部目标。两者故意发布相同包名,使共享代码导入一个符号即可由目标决定解析到哪一份副本。但两者并不同步发版,平台厂商的版本线往往更靠前,于是同一符号可能在两边具有不同形态。示例中,Menu 在多平台移植版里是 MenuBoxScope 的成员函数,在平台厂商的较新版本里则改为顶层扩展函数。两种情形下的调用点写法相同,导入写法不同:成员函数无需额外导入,顶层扩展必须按名导入。因此只导入 MenuBoxScope 的文件在移植版上可编译、在平台厂商产物上失败,反之亦然。
主要能力
- 指出兼容两种形态的做法:保留带理由注释的通配符导入(import <ui>.material3.*),并强调该通配符是承重的,不能按常规风格指南展开。
- 区分本机制与「传递版本锁定」:后者是解析问题,由严格约束选中非预期版本,在运行时于无关组件失败;本问题是导入形态问题,两个版本有意共存,在刚编辑的文件中编译期失败,两种修复互不替代。
- 列出若干陷阱:先查版本目录中是否存在同名工件分属不同 group 的重复坐标;通配符导入与偷懒写法外观相同,需在上方写明哪个厂商在哪个版本移动了哪个符号;后加的无理由通配符会污染审查;只升级平台厂商属于源码变更而非依赖变更,编译中断会落在未改动的 UI 文件;在版本目录中为两侧内联写明原因以固定版本,并记录两条版本线的近似对应关系,便于判断符号是否已发生偏移;偏移会随时间双向变化,移植版追平后通配符从必要变为无害,注释需写明退出条件(追平到移动该符号的版本后展开导入);不要通过把文件移入平台源集来「修复」,因为调用点本就是共享的,拆成两个 actual 会为一行导入复制整个 composable 并造成真实分叉。
- 提供验证步骤(均在仓库根目录运行):用 grep/sed/sort/awk 组合检查版本目录中是否存在同名工件对应两个不同 group 的重复坐标(测试专用配对属噪声,UI 工具包出现两次即为发现);逐文件检查共享源码中的通配符导入,上一行为注释则记为 documented,否则为 UNDOCUMENTED,通过条件是共享源集内全部为 documented;用 grep 读取 build.gradle.kts 依赖块,确认共享块使用多平台移植版、平台块使用平台厂商产物;任一版本线升级后对全部目标编译共享源集,单目标 assemble 不足以作为证据。
使用方式 技能本身以说明与命令片段形式给出,未提供安装命令或自动化脚本入口;所需信息暂未提供。按文中步骤在仓库根目录执行相应命令即可复核。
适用场景 适用于以 Kotlin Multiplatform 构建共享 UI、同时依赖平台厂商产物与多平台移植版、且两者发布同一包名的项目,尤其是共享源码出现「仅某一目标编译失败」的导入错误时。
限制 文中未给出具体版本号、厂商名称与包名,均以占位符呈现;未说明适用范围之外的构建配置;未提供工具化安装或集成方式。