美文网首页
Kotlin 实现Rust风格Result

Kotlin 实现Rust风格Result

作者: Gascognya | 来源:发表于2021-10-16 16:59 被阅读0次
sealed interface KResult<T, E>{
    fun bool(): Boolean = this is Ok

    fun option(): T? = when(this){
        is Err -> null
        is Ok -> value
    }

    fun <U> map(op: (T) -> U): KResult<U, E> = when(this){
        is Err -> err(this)
        is Ok -> ok(op(value))
    }

    infix fun and(other: KResult<T, E>): KResult<T, E> = when(this){
        is Err -> other
        is Ok -> this
    }

    infix fun or(other: KResult<T, E>): KResult<T, E> = when(this){
        is Err -> other
        is Ok -> this
    }

    fun <U> andThen(op: (T) -> KResult<U, E>): KResult<U, E> = when(this){
        is Err -> err(this)
        is Ok -> op(value)
    }
    
    fun <U> orElse(op: (E) -> KResult<T, U>): KResult<T, U> = when(this){
        is Err -> op(error)
        is Ok -> ok(this)
    }

}

data class Ok<T, E> internal constructor(val value: T): KResult<T, E>
data class Err<T, E> internal constructor(val error: E): KResult<T, E>

fun <T, E> ok(value: T): KResult<T, E> = Ok(value)
fun <T, E> ok(old: Ok<T, *>): KResult<T, E> = old as KResult<T, E>
fun <E> ok(): KResult<Any?, E> = Ok(null)

fun <T, E> err(error: E): KResult<T, E> = Err(error)
fun <T, E> err(old: Err<*, E>): KResult<T, E> = old as KResult<T, E>
fun <T> err(): KResult<T, Any?> = Err(null)

fun<T> T?.asRes(): KResult<T, Any?> = if (this == null) err() else ok(this)
fun<T, E> T?.asRes(error: E): KResult<T, E> = if (this == null) err(error) else ok(this)

fun<T> Optional<T>.res(): KResult<T, Any?> = if (isEmpty) err() else ok(get())
fun<T, E> Optional<T>.res(error: E): KResult<T, E> = if (isEmpty) err(error) else ok(get())

fun<T> Result<T>.res(): KResult<T, Any?> = if (isFailure) err() else ok(getOrThrow())
fun<T, E> Result<T>.res(error: E): KResult<T, E> = if (isFailure) err(error) else ok(getOrThrow())

因为kotlin也可以像rust那样,通过返回值类型反向推导泛型。这样有实际意义的Result成为可能。

起名IResult是因为kotlin自带一个简单的Result。会产生命名冲突。故采用C#接口命名法作为新名称

Empty是个简单的Any?别名,因为在只有半边有值的情况下,为了能写null值。IResult<Any?, T> 和IResult<T, Any?>可以改写为IResult<Empty, T>, IResult<T, Empty>
当然你也可以写个新的IResult<TOk>, IResult<TErr>,但是因为Kotlin不能像C#那样识别出来不同,所以同名不同泛型在Kotlin中是不允许的。你可以改个名,当然前提是你觉得足够优雅。

上述代码只是今天随便弄的简版,你可以所以加糖

相关文章

  • Kotlin 实现Rust风格Result

    因为kotlin也可以像rust那样,通过返回值类型反向推导泛型。这样有实际意义的Result成为可能。 起名IR...

  • Rust的问号操作符?

    rust-lang地址 Rust的异常处理是通过 Result 的 Ok 和 Err 成员来传递和包裹错误信息.然...

  • dart null safety

    很多语言都有 null safety 的问题,dart 会在 2.9 解决这个问题(rust 中通过 Result...

  • vs code 配置rust开发环境

    实现的需求: 查看宏定义,代码补全, 安装这三个插件: Rust,Rust Test Lens,rust-anal...

  • Rust 学习笔记 - 函数

    Rust 是一门多范式的编程语言,但 Rust 的编程风格是更偏向于函数式的,函数在 Rust 中是“一等公民”。...

  • Rust实现的密码学库介绍

    主要介绍rust-crypto和tiny-keccak这两个Rust实现的密码学库。 rust-crypto Ru...

  • Holochain 和 Mozilla CFO接触后的改变

    holochain的代码库中加入了holochain-rust(rust语言的实现) holochain为什么放弃...

  • Kotlin风格

    DTO 使用Data标识一个类为数据处理类,自带如下方法: getter/setter toString hash...

  • Kotlin实现单例模式

    java 内部类实现 kotlin object对象实现 方式一 kotlin 伴生对象实现 方式二

  • 二分搜索树

    Java实现: Kotlin实现:

网友评论

      本文标题:Kotlin 实现Rust风格Result

      本文链接:https://www.haomeiwen.com/subject/majwoltx.html