当我在Kotlin中使用Elvis操作时,可以添加回报吗?

我已经在http://mings.in/2017/03/12/Kotlin-Null-Safety.html上读过Elvis Operator

代码A和代码C是可以的,但是代码B是错误的(“types不匹配:推断types是Int但是Unit是预期的”),为什么?

代码A

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val b: String? = "hello" val l = b?.length ?: -1 } 

代码B

  override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val b: String? = "hello" val l = b?.length ?: return -1 } 

代码C

  fun getLength(b: String?): Int { val l = b?.length ?: return -1 return l } 

顺便说一句,BakaWaii告诉我:“代码A是好的,因为-1是一个expression式,所以它可以被赋值给l,但是在代码B中,返回-1是一个从函数返回的expression式。

我不明白“在代码B中,返回-1是一个从函数返回的expression式”。 我认为“返回-1”将返回-1,为什么该应用程序发生“types不匹配:推断types是Int,但单位是预期的”?

和更多:

代码C就像代码B,我不知道为什么它是好的!

Code ACode B之间的区别是第一个将-1设置为您的variables(现在是l ),第二个设置-1作为函数工作的结果。 和Type mismatch错误消息说,函数不应该返回任何值(或返回Unit ),但你正在尝试返回int – 所以这不是埃尔维斯运算符语法错误。

那么如果你把你的Code B放在一些Int函数中(就像你在Code C做的那样),就不会有任何错误。

如果你想“转换” IntStringBuilder你可以这样做:

 fun toStringBuilder(i: Int?): StringBuilder { val result = i?.toString() ?: "" return StringBuilder(result) } 

猜猜没有问题。

第二个例子也是绝对正确的。

 fun toStringBuilder(i: Int?): StringBuilder { val result = i?.toString() ?: return StringBuilder() return StringBuilder(result) } 

如果参数值为null函数将不会到达第二行,因为它将首先返回。

第三个例子会产生错误(就像你的Code B )。

 fun toStringBuilder(i: Int?): StringBuilder { val result = i?.toString() ?: return "" return StringBuilder(result) } 

再次,语法没有错误。 猫王操作员是正确的。 错误是因为你正试图返回String来作为返回StringBuilder声明的函数。

从Kotlin的文档 :

如果?:左边的expression式不为空,则elvis运算符返回它,否则返回右边的expression式。 请注意,由于throwreturn是Kotlin中的expression式,因此它们也可以在elvis运算符的右侧使用。

而且,

return 。 默认情况下从最近的封闭函数或匿名函数返回。

所以,答案是肯定的,只要封闭函数的返回types与返回值匹配,例如:

 fun getLength(b: String?): Int { val l = b?.length ?: return -1 //return an `Int` //if return -1, the code below will not execute return l } 

请注意,代码A和代码B在控制流程中是不同的。 如果在左侧值为空时尝试分配替代/默认值,则代码A将是最好的方法。