创建自定义扩展时保留智能广播 [英] Retain smartcast when creating custom extension

查看:51
本文介绍了创建自定义扩展时保留智能广播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前必须写

val myList: List<Int>? = listOf()
if(!myList.isNullOrEmpty()){
    // myList manipulations
}

哪个智能广播myList不能为非null.以下没有提供任何智能广播:

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()
}

有没有办法为自定义扩展获取smartCast?

解决方案

此问题通过科林1.3 中引入的rel ="noreferrer">合同. /p>

合同是一种通知编译器您函数的某些属性的方法,以便它可以执行一些静态分析,在这种情况下,请启用智能强制转换.

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()
}

您可以参考isNullOrEmpty的出处并查看类似的合同.

contract {
    returns(false) implies (this@isNullOrEmpty != null)
}

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?

解决方案

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)
}

这篇关于创建自定义扩展时保留智能广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆