【问题标题】:Kotlin function syntaxKotlin 函数语法
【发布时间】:2018-02-12 13:24:07
【问题描述】:

我正在进行 Kotlin Koans 测试以熟悉 Kotlin。在某个测试中,我必须重写 compareTo 方法。在第一种情况下,一切都按预期工作

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) {

    operator fun compareTo(other: MyDate)= when {
        year != other.year -> year - other.year
        month != other.month -> month - other.month
        else -> dayOfMonth - other.dayOfMonth
    }

}

现在,在第二种情况下,我编写compareTo 的方式略有不同,我得到了大量的编译错误。

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) {


     operator fun compareTo(other: MyDate){

        when {
            year != other.year -> return year - other.year
            month != other.month -> return month - other.month
            else -> return dayOfMonth - other.dayOfMonth
       }
     }


 }

首先,在 operator 关键字处,我得到一个错误:

'operator'修饰符不适用于此函数:必须返回 Int

在我得到的回报中

类型不匹配:推断类型为 Int 但应为 Unit

我不明白为什么会出现这些错误,因为第一个实现返回相同的 Ints

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    只是对@Mibac 的回答的补充:你可以把它缩短一点:

    operator fun compareTo(other: MyDate) = when {
        year != other.year -> year - other.year
        month != other.month -> month - other.month
        else -> dayOfMonth - other.dayOfMonth
    }
    

    【讨论】:

      【解决方案2】:

      这是因为 ={ return X } 一样工作这仅适用于函数定义。所以这意味着在第一个例子中你的代码等于这个

      operator fun compareTo(other: MyDate):Int {
          return when {
              year != other.year -> year - other.year
              month != other.month -> month - other.month
              else -> dayOfMonth - other.dayOfMonth
          }
      }
      

      但在第二个示例中,您没有返回 when 的结果。这会导致编译器感到困惑,因为它希望您返回 Int,但您却返回 Unit(相当于 Java 的 void

      所以你需要做的就是给它添加一个显式的返回类型(Int)(fun X(/*args*/): Int 或其他适用的类型)

      【讨论】:

      • 这有点不对劲。当你写fun someFunction(a: Type) { }(没有=)时,Kotlin 总是会推断出返回类型是Unit。不管他在when之前有return,还是在里面。
      • 跟进我的上一条评论;他唯一需要添加的是函数定义的返回类型 (: Int)。您无需将return 放在when 之前,因为when 表达式的else 分支使其详尽无遗。
      • 是的,你当然需要returnsomewhere。您可以在 when 表达式的每个分支中使用它,就像他在“第二种情况”中所做的那样。这就是我的观点。
      【解决方案3】:

      在您的第一个示例中,compareTo(MyDate) 的返回类型为 inferredInt,因为 when 表达式的所有分支都返回 Int

      在您的第二个示例中,compareTo(MyDate) 的返回类型是 Unit。由于您的函数具有块体,因此必须明确指定返回类型(除非它打算让它们返回Unit)。所以,Unit 应该是这里的返回类型,但是从你的when 表达式推断的返回类型是Int。这就是您收到错误的原因:

      类型不匹配:推断类型为 Int 但应为 Unit

      这里是official explanation,用于显式定义带有块体的函数的返回类型:

      具有块体的函数必须始终明确指定返回类型,除非它打算让它们返回 Unit,in which case it is optional。 Kotlin 不会为带有块体的函数推断返回类型,因为这样的函数在体中可能具有复杂的控制流,并且返回类型对读者来说是不明显的(有时甚至对编译器来说也是如此)。

      所以,声明compareTo(MyDate)的正确方法是指定函数的返回类型,如果它包含块体:

      operator fun compareTo(other: MyDate): Int {
          when {
              year != other.year -> return year - other.year
              month != other.month -> return month - other.month
              else -> return dayOfMonth - other.dayOfMonth
          }
      }
      

      这同时解决了另一个错误,因为comparison operator 需要返回Int

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-15
        • 2019-01-11
        • 1970-01-01
        • 2018-02-17
        • 2018-08-16
        • 1970-01-01
        相关资源
        最近更新 更多