无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
的内容,删除key
input
的值,使得
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 }