TL; DR:看看这个游乐场 。
这有点-可能通过科特林合同-科特林1.3的一个实验性的功能,以提高支持智能施法的。
以下是contract一个简单示例:
@ExperimentalContracts
fun Object?.isNotNull(): Boolean {
contract {
// If I return "true", then it means that I am not null
returns(true) implies (this@isNotNull != null)
}
return this != null
}
if (obj.isNotNull())
print(obj.value) // smart-cast applied.
现在我在这里说,因为合同的使用有一些限制。 只有顶级功能支持它们。 这意味着您必须创建Object类的扩展。 另一个限制是我们想在这里检查Object.value空性,而不是Object本身。 合同定义不支持此功能。 所以即使它看起来很理想,下面的代码也不会编译:
@ExperimentalContracts
fun Object.doesNotContainNull(): Boolean {
contract {
// The following line gives an error:
// Error in contract description: only references to parameters are allowed in contract description.
returns(true) implies (this@doesNotContainNull.value != null) }
return value != null
}
如错误所示,我们可以参考合同描述中的参数。 因此,我们可以提出一种将value作为参数传递的解决方法。 最后,该函数将如下所示:
@ExperimentalContracts
fun Object.doesNotContainNull(value: Int?): Boolean {
contract {
returns(true) implies (value != null)
}
return value != null
}
if (obj.doesNotContainNull(obj.value)) {
passNonNullableValue(obj.value) // smart cast applied!
}
尽管这种方法有效,但它很危险,因为调用者可能并不总是将obj.value作为参数传递。 因此,如果检查失败,我们希望确保条件并抛出运行时错误。
@ExperimentalContracts
fun Object.doesNotContainNull(value: Int?): Boolean {
contract {
// "If I return true, then it means that $value is not null."
returns(true) implies (value != null)
}
if(value != this.value)
throw IllegalArgumentException("$value must be ${this.value}")
return value != null
}
完整的例子可以在这个游乐场玩。