Retain smartcast when creating custom extension

社会主义新天地 提交于 2021-01-27 06:07:11

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!