Kotlin Multiplatform for OpenHarmony 实战:kotlin-result 类型化错误处理适配

摘要
本文记录 kotlin-result 三方库在 OpenHarmony 上的鸿蒙化适配过程。ArkTS 没有原生 Result 类型,我们通过「纯语义复刻」路线,用 Ok/Err 两个分支 + 一组不丢错误信息的链式组合子,完整还原了 Kotlin 类型化错误处理的开发体验。全文按三层架构展开:语义层(Result.ets)、引擎层(OhosResultEngine)、验收页(ResultDemo),并附真机验证与踩坑小结。
目录
- 一、为什么选它
- 二、适配总思路:三层架构(纯语义复刻,零 @kit)
- 三、语义层:Ok/Err 与组合子
- 四、引擎层:resultOf 等价 runCatching
- 五、验收页:真机上验证
- 六、踩坑小结
- 总结
- 社区引导
本文是 KMP 三方库鸿蒙化适配,聚焦 kotlin-result(Rust 风格 Result<T,E>)的 OpenHarmony 适配。我们只讲本仓库真实落地的代码,不做系列横向对比。
一、为什么选它
kotlin-result 是 Kotlin 社区广泛使用的类型化错误处理库(灵感来自 Rust 的 Result):用 Result<T, E> = Ok<T> | Err<E> 把「可能失败」显式编码进类型,配合 map / flatMap / mapError / recover / onSuccess / onFailure 等组合子,彻底告别 try/catch 与异常透传。
到了 OpenHarmony,ArkTS 没有原生 Result 类型,但类型化错误的思想完全可以「等价复刻」——Ok/Err 两个分支 + 一组不丢错误信息的链式组合子,让 KMP 源码里的 runCatching { }.map { }.recover { } 写法在鸿蒙侧有一一对应的实现。这也是本系列「纯语义复刻」路线的延续。
二、适配总思路:三层架构(纯语义复刻,零 @kit)
- 语义层(零
@kit.*):Ok<T,E>/Err<T,E>+map/flatMap/mapError/recover/onSuccess/onFailure/getOrElse/getOrThrow,不碰任何平台 API。 - 引擎层(无系统桥接):
OhosResultEngine提供resultOf(等价于 KotlinrunCatching)与错误归一化,与系列纯逻辑引擎层定位一致。 - 验收页:
ResultDemo在真机/模拟器上做除零错误、链式变换、兜底恢复、异常捕获。
三、语义层:Ok/Err 与组合子
Result.ets 只有一个 Result<T,E> 接口 + Ok/Err 两个实现(注意 ArkTS 严格模式禁止构造参数属性,字段显式赋值):
export class Ok<T, E> implements Result<T, E> {
readonly isSuccess: boolean = true;
readonly isFailure: boolean = false;
private value: T;
constructor(value: T) { this.value = value; }
map<U>(f: (v: T) => U): Result<U, E> { return new Ok<U, E>(f(this.value)); }
flatMap<U>(f: (v: T) => Result<U, E>): Result<U, E> { return f(this.value); }
recover(f: (e: E) => T): Result<T, E> { return this; } // 成功分支 recover 透传
}
export class Err<T, E> implements Result<T, E> {
readonly isSuccess: boolean = false;
readonly isFailure: boolean = true;
private error: E;
constructor(error: E) { this.error = error; }
map<U>(f: (v: T) => U): Result<U, E> { return new Err<U, E>(this.error); }
flatMap<U>(f: (v: T) => Result<U, E>): Result<U, E> { return new Err<U, E>(this.error); }
recover(f: (e: E) => T): Result<T, E> { return new Ok<T, E>(f(this.error)); } // 失败分支 recover 兜底
}
要点:
- 错误不丢:
map/flatMap在Err分支直接「短路穿透」,错误信息原样保留,绝不吞掉。 recover是兜底关键:Err分支调用recover把错误转成正常值,从此变回Ok,这正是 Kotlin 里recover { fallback }的语义。getOrThrow忠于原意:Err分支调用即抛异常(携带错误描述),Ok分支直接返回值。
四、引擎层:resultOf 等价 runCatching
OhosResultEngine.ets 没有系统 API 可桥接,提供把「可能抛异常的块」包成 Result 的能力:
export class OhosResultEngine {
resultOf<T>(block: () => T): Result<T, Error> {
try {
return ok<T, Error>(block());
} catch (e) {
const errObj: Error = (e instanceof Error) ? e : new Error(String(e));
return err<T, Error>(errObj);
}
}
}
这正好对应 Kotlin 标准库的 runCatching { ... }——把异常转成 Err,业务代码从此「显式处理错误」而非「靠异常隐式透传」。
五、验收页:真机上验证
本项目开发代码界面如下:

ResultDemo.ets 四个按钮:
- 除法(除零→Err):
safeDiv(10,0)返回Err("除数不能为 0"),onFailure上屏——证明错误被显式建模。 - map/flatMap 链式:
Ok(5).map(*2).flatMap(+1)得到Ok(11),证明成功分支的链式变换。 - recover 兜底:
Err("上游失败").recover(_ => -1)变成Ok(-1)——证明失败可被优雅兜底。 - resultOf 捕获异常:
resultOf { throw Error("boom") }返回Err(Error: boom)——证明异常被捕获进Result而非崩溃。
运行一遍,结果区会显示类型化错误处理的完整闭环,证明 kotlin-result 在鸿蒙真实可用。




六、踩坑小结
Ok/Err都要实现全部组合子:组合子定义在两个类上才能多态调用,Err分支的map必须「穿透」而非计算。- 严格模式禁止构造参数属性:
constructor(value: T)内必须显式this.value = value。 catch (e)的类型:ArkTS 里用e instanceof Error判定后转成Error,避免把不确定类型直接塞进Err。getOrThrow的报错信息:Err分支用JSON.stringify兜底序列化非字符串错误,保证抛出的Error.message可读。
总结
本次适配用「纯语义复刻」路线,把 Rust 风格的 Result<T,E> 完整搬到了 OpenHarmony:
- 语义层:
Ok/Err两个实现类 +map/flatMap/recover等组合子,错误信息在Err分支「短路穿透」绝不丢失。 - 引擎层:
OhosResultEngine.resultOf等价 KotlinrunCatching,把异常显式转成Err,业务代码从此告别隐式异常透传。 - 验收页:四个按钮覆盖除零错误、链式变换、兜底恢复、异常捕获,在真机上跑通完整闭环。
关键收获:ArkTS 严格模式虽禁止构造参数属性,但类型化错误的思想不受平台限制——只要组合子定义到位、Err 分支正确「穿透」,KMP 源码里的 runCatching { }.map { }.recover { } 写法就能在鸿蒙侧一一对应。源码已开源在 AtomGit,欢迎对照使用。
欢迎加入 KMP&CMP 鸿蒙社区:https://atomgit.com/CPF-KMP-CMP
本适配全部源码已开源在 AtomGit:https://atomgit.com/wdracky/kmp-ohos-adapters/tree/main/kotlin-result
如果你在适配过程中用到了 AI 辅助工具,推荐码道(AtomCode)专属通道
https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwatomgit1&sourcead=dmzntgwatomgiths
更多推荐




所有评论(0)