首页 文章

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

提问于
浏览
1

我在http://mings.in/2017/03/12/Kotlin-Null-Safety.html读过猫王操作员

代码A和代码C都没问题,但是代码B是错误的(“类型不匹配:推断类型是Int但单位是预期的”),为什么?

Code A

override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)  

      val b: String?  = "hello"
      val l = b?.length ?: -1
 }

Code B

override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)

      val b: String?  = "hello"
      val l = b?.length ?: return -1

    }

Code C

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

BTW,BakaWaii告诉我“代码A没问题,因为-1是表示值的表达式,因此它可以分配给l . 但是在代码B中,返回-1是从函数返回的表达式 . ”

我无法理解“在代码B中,返回-1是一个从函数返回的表达式” . 我认为“返回-1”将返回-1,为什么应用程序出现“类型不匹配:推断类型是Int但单位是预期的”?

And more:

代码C就像代码B一样,我不知道为什么它可以!

2 回答

  • 2

    Code ACode B 之间的区别是第一个将 -1 设置为您的变量(现在它是 l ),第二个设置 -1 作为函数工作的结果 . 并且 Type mismatch 错误消息表示该函数不应返回任何值(或返回 Unit ),但您尝试返回int - 因此它不是Elvis运算符语法错误 .

    然后,如果您将 Code B 放在某个 Int 函数中(就像在 Code C 中那样),就不会有任何错误 .

    Example

    如果你想"convert" 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 的函数 .

  • 3

    来自Kotlin's doc

    如果?:左边的表达式不为null,则elvis运算符返回它,否则返回右边的表达式 . 请注意,由于throw和return是Kotlin中的表达式,因此它们也可以在elvis运算符的右侧使用 .

    also

    回归 . 默认情况下,从最近的封闭函数或匿名函数返回 .

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

    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在控制流程中是不同的 . 如果您在左侧值为null时尝试分配备用/默认值,则代码A将是最佳方法 .

相关问题