【问题标题】:Kotlin - return type of current instanceKotlin - 当前实例的返回类型
【发布时间】:2018-04-06 21:07:27
【问题描述】:

我正在 Kotlin 中构建一个验证库。基类是abstract,实现了适用于所有类型的方法; isNotNull 例如:

abstract class Validator<V>(protected val value: V?) {
    fun isNotNull(): Validator<V> {
        if(value == null) {
            // ... some validation handling here ...
        }

        return this
    }
}

然后我对特定类型的验证器进行子分类:

class IntValidator(value: Int?) : Validator<Int>(value) {
    fun isNotZero(): IntValidator {
        if(value == 0) {
            // ... some validation handling here ...
        }

        return this
    }
}

现在说我想验证一个 Int?不为空也不为零

val validator = IntValidator(myNullableInteger)

validator
    .isNotNull()
    .isNotZero()

上面的代码不起作用,因为.isNotNull()返回Validator&lt;V&gt;,而不是IntValidator,所以.isNotZero()不再在范围内。

方法有没有办法返回实例化它们的类型(在我的例子中,我希望它返回IntValidator,而不是Validator&lt;T&gt;)?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    也许您应该重新考虑 API 设计。不链接方法而是使用作用域函数怎么样?

    val validator = IntValidator(myNullableInteger)
    with(validator) {
        isNotNull()
        isNotZero()
    }
    

    IntValidator 的范围内,这两种方法都可以访问。

    【讨论】:

    • 这实际上被证明是最优雅的解决方案。
    【解决方案2】:

    一种方式,但使用未经检查的演员表:

    fun main(args: Array<String>) {
      val validator = IntValidator(2)
    
      validator
        .isNotNull()
        .isNotZero()
    }
    
    abstract class Validator<V, out R>(protected val value: V?) {
        open fun isNotNull(): R {
            if(value == null) {
                // ... some validation handling here ...
            }
    
            return this as R
        }
    }
    
    class IntValidator(value: Int?) : Validator<Int, IntValidator>(value) {
        fun isNotZero(): IntValidator {
            if(value == 0) {
                // ... some validation handling here ...
            }
    
            return this
        }
    }
    

    【讨论】:

    • 不是我见过的最性感的东西,但必须! +1
    【解决方案3】:

    正如this kotlinlang thread 所讨论的,您可以为此使用扩展方法:

    abstract class Validator<V>(internal val value: V?)
    fun <T: Validator<U>, U> T.isNotNull(): T {
        if(this.value == null) {
            // ... some validation handling here ...
        }
        return this
    }
    
    class IntValidator(value: Int?) : Validator<Int>(value)
    
    @Suppress("FINAL_UPPER_BOUND")
    fun <T: IntValidator> T.isNotZero(): T {
        if (this.value == 0) {
            // ... some validation handling here ...
        }
        return this
    }
    
    fun main() {
        val validator = IntValidator(0)
        validator
                .isNotNull()
                .isNotZero()
    }
    

    这使您可以将对象类型用作函数的通用参数,这意味着您也可以接收对象类型作为结果。通用边界允许您在返回调用实例的类型时使用类型安全。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      相关资源
      最近更新 更多