我正在尝试获取一个类,该类结合了中的list,set和map Kotlin
。我希望编写isScalar
函数,true
如果对象仅包含一个元素并编写,它将返回
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap
import it.unimi.dsi.fastutil.objects.ReferenceArrayList
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
class Args {
var list : ReferenceArrayList<M>? = null
var set : ReferenceOpenHashSet<M>? = null
var map : Reference2ReferenceOpenHashMap<M, M>? = null
fun isEmpty() : Boolean {
return list === null && set === null && map === null
}
fun isScalar() : Boolean {
if(list !== null && list.size == 1) {
return true
}
}
}
不幸的是,相比之下,它给了我错误
list !== null && list.size == 1
说
Smart cast to 'ReferenceArrayList<M>' is impossible, because 'list' is a mutable property that could have been changed by this time
据我了解,这与多线程假设有关。在Java中,synchronized
如果期望多用途,我将使函数生效。另外,如果我不写线程安全的话,我将完全可以忽略这一点。
我应该如何用Kotlin写作?
我看到了这个解决方案https://stackoverflow.com/a/44596284/258483,但是它期望MT,我不想这么做。如果无法做到,如何避免进行智能投射?
更新
问题是如何以相同的“过程”形式执行此操作。如何不使用智能铸造?
更新2
总结,据我所知,null
在Kotlin中根本不可能将变量与进行显式比较。因为一旦比较完之后,下一次您将不得不null
再次使用类似的操作将其与之隐式比较,.?
而您将无法避免这种情况。
如果您利用null
不能相等的事实1
(或其他任何事实),则可以使此检查非常简洁:
fun isScalar() : Boolean =
list?.size == 1
当对null的安全调用list.size
返回null时,我们得到false
因为1 != null
。否则,size
将对返回的任何值进行比较,这将按您期望的那样工作。
通过使用null安全运算符(?.
),您可以完全避免进行智能转换。Kotlin为我们提供了精巧的强制转换,以使代码更整洁,这是保护我们免受该功能滥用的一种方式。Kotlin不会保护我们免受一切影响(例如,零除,例如您在评论中使用的示例)。您的代码正陷入智能浇铸可能出错的合法情况,因此Kotlin会提供帮助。
但是,如果您完全确定没有其他线程在工作,那么可以,此检查是“错误的”。在这种情况下,您将不需要警告。从kotlinlang.org上的该线程来看,您不是唯一的一个!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句