问题
I currently have to write
val myList: List<Int>? = listOf()
if(!myList.isNullOrEmpty()){
// myList manipulations
}
Which smartcasts myList to no non null. The below do not give any smartcast:
if(!myList.orEmpty().isNotEmpty()){
// Compiler thinks myList can be null here
// But this is not what I want either, I want the extension fun below
}
if(myList.isNotEmptyExtension()){
// Compiler thinks myList can be null here
}
private fun <T> Collection<T>?.isNotEmptyExtension() : Boolean {
return !this.isNullOrEmpty()
}
Is there a way to get smartCasts for custom extensions?
回答1:
This is solved by contracts introduced in Kotlin 1.3.
Contracts are a way to inform the compiler certain properties of your function, so that it can perform some static analysis, in this case enable smart casts.
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@ExperimentalContracts
private fun <T> Collection<T>?.isNotEmptyExtension() : Boolean {
contract {
returns(true) implies (this@isNotEmptyExtension != null)
}
return !this.isNullOrEmpty()
}
You can refer to the source of isNullOrEmpty
and see a similar contract.
contract {
returns(false) implies (this@isNullOrEmpty != null)
}
来源:https://stackoverflow.com/questions/57670014/retain-smartcast-when-creating-custom-extension