以下情况:我尝试实现一个泛型函数,该函数检查变量列表是否全部都不为null并执行一个lambda,它需要不可为空的变量。
我可以使用2,3,4 ...自变量链接多个let调用或实现多个'safeLet'-Function,但是我仍然希望可以使用一个带有列表的泛型函数。
此处是带有链接的let-call的当前代码:
val parameters = call.receiveParameters()
val firstName = parameters["firstName"]
val lastName = parameters["lastName"]
firstName?.let {
lastName?.let { userService.add(UserDTO(firstName = firstName,lastName = lastName)) }
}
这是我当前的“ safeLet”功能:
fun <T> List<Any?>.safeLet(block: () -> T) {
if(this.contains(null)) return
block()
}
但是以下内容仍然无法编译(因为UserDTO的参数是String而不是String?):
listOf(firstName,lastName).safeLet {
userService.add(UserDTO(firstName = firstName,lastName = lastName))
}
我可以添加!在firstName和lastName之后,以避免进行nullcheck,但这很丑。
我的想法是使用Kotlin合同。可能是这样的:
@ExperimentalContracts
fun <T> List<Any?>.safeLet(block: () -> T) {
contract {
returnsnotNull() implies {ALL ELEMENTS ARE NOT NULLABLE}
}
if(this.contains(null)) return
block()
}
谢谢。
关于“ filterNotNull”注释,我现在尝试了。仍然不理想,因为我不喜欢在这里使用this [0]和this [1],但是它可以工作:
allNotNull(firstName,lastName)?.apply {
userService.add(UserDTO(firstName = this[0],lastName = this[1]))
}
fun <T : Any> allNotNull(vararg elements: T?): List<T>? = if(elements.contains(null)) null else elements.filterNotNull()