2017-09-04 20 views
0

私はKotlinに慣れるためにKotlin Koansのテストをしています。あるテストでは、compareToメソッドをオーバーライドする必要があります。最初のケースのすべての仕事で、私は少し違った私はコンパイルエラーのトンを取得compareToを書いている第二の場合には今Kotlin関数の構文

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 
    } 

} 

を意図したとおり。

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' modifier is inapplicable on this function: must return Int

及びこれらのエラーがあるため発生し、なぜ私は

Type mismatch: inferred type is Int but Unit was expected

を得るリターンで私が理解することはできません最初の実装では同じものが返されますInt s

答えて

1

=は、{ 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)だから、あなたがする必要があるすべては明示的な戻り値の型を追加することです

それはあなたがIntを返すことが予想されるので、それは混乱しているコンパイラになりますが、あなたはUnit代わりに(Javaのvoidに相当)を返しますwhen式のすべてのブランチがIntを返すので、それは(fun X(/*args*/): Intまたはその他の適用可能なタイプ)

+0

これは少しオフがある:あなたはこの少し短くすることができます。 'fun someFunction(a:Type){}'( '='なしで)を書くと、Kotlinは戻り値の型が 'Unit'であると常に推測します。彼が 'いつ'の前に '戻り'を持っているのか、それとも内部にあるのかは関係ありません。 – marstran

+0

最後のコメントをフォローアップする。彼が追加する必要があるのは、関数定義に対する戻り値の型( ':Int')だけです。 when式のelseブランチが完全なものになるので、 'when'の前に' return'を置く必要はありません。 – marstran

+0

@marstran [ちょうどチェックし、あなたはリターンが必要です](https://try.kotlinlang.org/#/UserProjects/dcmc5bt52isgk4rhc2ule8toe0/s67it8ebb3i30m05j3870qqj8h) – Mibac

2

あなたの最初の例では、compareTo(MyDate)の戻り値の型はIntとしてinferredです。

第2の例では、返品タイプcompareTo(MyDate)Unitです。あなたは関数がブロック本体を持っているので、戻り値の型は明示的に指定しなければなりません(戻り値はUnitです)。戻り値の型はUnitとなりますが、when式から推測される戻り値の型はIntです。あなたがエラーを取得する理由です:

Type mismatch: inferred type is Int but Unit was expected

ここ

は、明示的にブロック体との機能の戻り値の型を定義するためのofficial explanationです:

Functions with block body must always specify return types explicitly, unless it's intended for them to return Unit, in which case it is optional . Kotlin does not infer return types for functions with block bodies because such functions may have complex control flow in the body, and the return type will be non-obvious to the reader (and sometimes even for the compiler).

ので、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 
    } 
} 

これは、以降の別のエラーを同時に解決します。 Intを返すには、が必要です。

0

@Mibacの答えにジャストほか:

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