我理解 Kotlin 的!!
操作符是做什么的。我想知道是否有任何用例可以更好地!!
代替?.let
or?: return
或其他更安全的空检查。
关于 null 安全性的Kotlin 文档只是说它适用于喜欢 NullPointerExceptions 的人;人们为什么要那些?
我主要只是好奇它是否有用例,没有更好的选择。
我理解 Kotlin 的!!
操作符是做什么的。我想知道是否有任何用例可以更好地!!
代替?.let
or?: return
或其他更安全的空检查。
关于 null 安全性的Kotlin 文档只是说它适用于喜欢 NullPointerExceptions 的人;人们为什么要那些?
我主要只是好奇它是否有用例,没有更好的选择。
不是每个人都是初学者。使用此运算符的感叹号有助于表示如果您确实使用它,您会更好地了解自己在做什么。
在某些情况下,它会产生更清晰的代码。我在使用第三方库时经常看到这种情况。
例如,Android 是LiveData.value
可以为空的,但如果你在初始化它时设置正确的值,那么你就知道该值永远不会为空。
val myLiveData = MutableLiveData<Float>().apply{ value = 1f }
这是一个见仁见智的问题,但我认为使用未使用的默认值乱扔对该 getter 的每个引用会非常嘈杂:
when ((myLiveData.value ?: 1f) > 0f) { /* */ }
对比
when (myLiveData.value!! > 0f) { /* */ }
就个人而言,如果我使用课堂外的实时数据,我不会使用双键,因为这样就无法明确保证它实际上有一个值集。但是在包含它的类中,您可以相信自己知道自己在做什么。
这是来自 Android 的另一个示例。当您在 PreferenceFragmentCompat 中工作并且需要获取 Preference 引用时,findPreference
如果首选项不在层次结构中,则使用返回 null。如果您知道 Preference 应该存在,那么使用它是有意义的,!!
因为如果它实际上不存在,您希望看到异常。或者,您可以使用?: error("missing preference")
,但它是额外的代码,并不能真正使堆栈跟踪中的问题更加明显。或者您可能很想使用findPreference("x")?.let { //... }
,但是当缺少首选项时它会默默地失败,如果您知道首选项应该在那里,这不是您想要的。
当然,使用时要小心!!
。如果您的特定 PreferenceFragment 通过在各种情况下添加和删除它们来对 Preferences 进行一些操作,那么在测试期间使用可能更合适的是?.let {/**/} ?: Log.e(...)
您错过了当您认为它会出现偏好不存在的情况时.
null
只要值表明代码本身不正确,您就会想抛出 NullPointerException 。就像如果无效参数表明调用者的代码不正确,您可能会显式抛出 IllegalArgumentException。
因此, for 的用例与 for 的用例!!
非常相似if(...) { throw ...; }
,但!!
更短。
如果代码不正确,您想了解它们,并立即使用堆栈跟踪停止程序是(1)通知程序员问题的好方法,以及(2)提供尽可能多的有用信息调试目的。