如果条件检查在另一个函数中,kotlin 智能转换不起作用

Fre*_*uvn 1 kotlin

例如:

fun test() {
    val s: String? = ""
    check(s != null)

    // Error: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
    s.subSequence(0, 1)
}

inline fun check(expression: Boolean) {
    if (!expression) {
        throw IllegalArgumentException()
    }
}
Run Code Online (Sandbox Code Playgroud)

check功能inline,所以它是一样的:

fun test() {
    val s: String? = ""
    //check(s != null)
    if (!(s != null)) {
        throw IllegalArgumentException()
    }

    // It worked!
    s.subSequence(0, 1)
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,即使使用contract,!= null也可以,但是!== null还是失败了

Ada*_*hip 5

如果您使用内置check()函数(抛出IllegalStateException),而不是您自己的自定义函数,则它可以正常工作。

如果你愿意IllegalArgumentException,你可以使用require().

如果您使用该@ExperimentalContracts属性并添加一个,则可以使编译器对自定义函数进行智能转换contract

@ExperimentalContracts
fun test() {
    val s: String? = ""
    myCheck(s != null)

    s.subSequence(0, 1) // smart cast
}

@ExperimentalContracts
inline fun myCheck(expression: Boolean) {
    contract {
        returns() implies expression
    }
    if (!expression) {
        throw IllegalArgumentException()
    }
}
Run Code Online (Sandbox Code Playgroud)