例如:
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
还是失败了
如果您使用内置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)