当我在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 A
和Code B
之间的区别是第一个将-1
设置为您的variables(现在是l
),第二个设置-1
作为函数工作的结果。 和Type mismatch
错误消息说,函数不应该返回任何值(或返回Unit
),但你正在尝试返回int – 所以这不是埃尔维斯运算符语法错误。
那么如果你把你的Code B
放在一些Int
函数中(就像你在Code C
做的那样),就不会有任何错误。
例
如果你想“转换” Int
到StringBuilder
你可以这样做:
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式。 请注意,由于throw
和return
是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将是最好的方法。