2016-12-10 11 views
0

スカラの初心者を完了し、今すぐ基本を理解しようとしています。スカラ型不一致ユニットの代わりに

私はチュートリアルの一部として、整数リストの中で最大の要素を返す関数を作成しようとしています。これを実現するために、私は、(仮称)しました一緒に次のコードを置く:私はそれをコンパイルしようとしたとき、私は私が持っているライン5

[error] /scala/example/src/main/scala/example/Lists.scala:5: type mismatch; 
[error] found : Unit 
[error] required: Int 
[error]   findMax(xs.head, xs.tail) 

の型エラーを取得し、しかし

def max(xs: List[Int]): Int = 
    if (xs.isEmpty) 
    throw new java.util.NoSuchElementException 
    else 
    findMax(xs.head, xs.tail) 

def findMax(a: Int, b: List[Int]) { 
    if (b.isEmpty) return a 

    if (a > b.head) 
    findMax(a, b.tail) 
    else 
    findMax(b.head, b.tail) 
} 

を私はこのエラーメッセージで混乱していることを認めています。コンパイラが、この行の前にリストが空でないことを保証するためにロジックを与えられたUnit型を渡そうとしていると、私は理解していません。

誰でも問題を明確にすることはできますか?

答えて

5

Scalaは関数を定義するための2つの構造を有する:

def doSomething(a: Int) { a + 3 } 

def doSomethingElse(b: Int) = { b + 3 } 

最初のものは、プロシージャ構文として知られており、それは貧弱な仮定と混乱コードにつながるので、それが推奨され。これらの2つの機能の違いは、doSomethingUnitを返しますが、doSomethingElseIntを返します。 =が含まれていない場合、関数は何も返しません(つまり、Unitを返します)。

この

def doSomething(a: Int) { a + 3 } 

はあなたがintを返すように機能 findMaxをしたい

def doSomething(a: Int): Unit = { a + 3 } 

と同等ですが、あなたは=をオフに左ので、ScalaはそれがUnitを返すと言います。これがコンパイルエラーの原因です。あなたは一般的にどちらかの書き込み

def findMax(a: Int, b: List[Int]) = { 

または

def findMax(a: Int, b: List[Int]): Int = { 

によってこの問題を解決することができ、あなたは、プロシージャの構文を使用しないでください。最終的に戻り値の型を型推論にしても、必ず=を使用してください。


あなたがあなたの関数でreturnを使用しているため最初のアプローチは、実際には、コンパイラエラーになるかもしれないことに留意すべきです。 returnを明示的に呼び出す関数は、関数ヘッダーで返される型を指定する必要があります。 Scalaは式ベースの言語なので、すべてのステートメントは式なので、値を返します。あなたは次のようにreturnを必要としないためにあなたのfindMax機能を書き換えることができます。

def findMax(a: Int, b: List[Int]): Int = { 
    if (b.isEmpty) 
    a 
    else if (a > b.head) 
    findMax(a, b.tail) 
    else 
    findMax(b.head, b.tail) 
} 
+0

プロシージャ構文は、-Xfutureの下で廃止されました。私はこれが理由だと思う。 –

+0

ありがとう、あなたは私が混乱していたよりもさらに多くのことを明らかにしました!フォローアップの質問をすることができますが、例外がスローされたときに返されるものについて説明できますか?具体的には、もともとは、if-else条件ではなく、ガード節の一部として2行目と3行目をまとめたかったのですが、これは型不一致(Intの代わりにUnit)を引き起こし、 "xs" findMax関数の呼び出しで使用される値はありません。 –

+0

'throws'は非常に特殊なケースです。それは返されません。スローされた例外の型をキャッチしない '試行 'もしません。この場合、 'throws'または' try'の戻り値の型は 'Nothing'という特別な底の型です。 'Nothing'のインスタンスはありません。' Nothing 'でさえもNothingではありません。 'Nothing'はすべてのサブタイプであるので、あるブランチでは' Nothing'を返し、もう一つは 'Int'を返す' if'はその2つのブランチの最も一般的な型であるため、最終的に 'Int'を返します。 – Zeimyth