无elvis运算符kotlin的空安全
无elvis运算符kotlin的空安全,kotlin,Kotlin,a?:b只是if(a!=null)a else b的简写 我知道?:消除了代码中空引用的危险。然而,我遇到了片段,我没能自己重新编写。这是: ` 但是Intelij在此处显示错误 在我将其替换为Sugestation之后,我发现了更多错误: words[input] = if (words[input] != null) (words[input]?.plus(1)) else 0 如果语句仍然存在,我如何修复它?val n=words[input] 单词[输入]=如果(n!=null)
a?:b
只是if(a!=null)a else b
的简写
我知道?:
消除了代码中空引用的危险。然而,我遇到了片段,我没能自己重新编写。这是:
`
但是Intelij在此处显示错误
在我将其替换为Sugestation之后,我发现了更多错误:
words[input] = if (words[input] != null) (words[input]?.plus(1)) else 0
如果语句仍然存在,我如何修复它?val n=words[input]
单词[输入]=如果(n!=null)n+1否则0
if
语句之后,words
可能会将值更改为null
,因此您应该先捕获变量,然后进行赋值
a?:b
只是if(a!=null)a else b的缩写
几乎是这样。 但是有一个细微的区别:猫王版本只对a
进行一次计算,而另一个版本则对其进行两次计算——这可能意味着它每次都会给出不同的结果
在这种情况下,a
是words[input]
。 如果另一个线程在两次求值之间更改words
的内容,删除keyinput
的值,使得words[input]
第二次返回null,该怎么办? (即使您知道没有其他线程可能访问它,如果编译器无法证明这一点,它也必须假设第二次可能会给出空结果。)
因此,解决方案是只评估一次
根据另一个答案,您可以使用一个临时变量来实现这一点。 但Kotlin的作用域函数为您提供了一个稍微简单的选项:
words[input].let{ if (it != null) it + 1 else 1 }
这是因为是在Any?
上定义的扩展方法,所以(与“real”方法不同)调用null是安全的
然而,这只是说明了为什么elvis运算符很有用,以及它是如何简化一些代码的! 您没有解释为什么要重写代码以避免它;这可能是一个有用的学习练习,但在实践中,您只需使用elvis运算符即可。为什么您首先要尝试删除elvis运算符的用法?为了便于记录,这里发生的情况是,words[input]
可能会在您在if
中检查它,然后在中评估它之间更改值。此外,应将1
添加到的结果中,如果不只是在中,那么branchI不理解您的答案。
words[input] = if (words[input] != null) (words[input]?.plus(1)) else 0
words[input].let{ if (it != null) it + 1 else 1 }