私はこのscalaコードに遭遇し、intを返すという事実を除いて、それが何をしているのかを解明しようとしています。私はこれらの3行がわかりません:
l match {
case h :: t =>
case _ => 0
働き :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
私はこのscalaコードに遭遇し、intを返すという事実を除いて、それが何をしているのかを解明しようとしています。私はこれらの3行がわかりません:
l match {
case h :: t =>
case _ => 0
働き :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
最初に、という関数を定義しiterate、戻り値の型を として指定しましたInt。アリティ 1、lタイプ のパラメーターがありますList[Int]。
型は関数型プログラミング全体で顕著であり、主な特徴は、効率的なプリペンドがあり、ヘッドとテールにList簡単に分解できることです。Listhead はリストの最初の要素 (空でない場合) になり、tail は残りの要素List(それ自体がList) になります。これは、 を操作する再帰関数に役立ちListます。
matchはパターン マッチングと呼ばれます。これは本質的に C っぽい言語のステートメントですswitchが、はるかに強力switchです。 は定数に制限します (少なくとも C ではそうです) が、 にはそのような制限はありませんmatch。
さて、あなたが最初caseに持っているh :: t- これ::は "cons" と呼ばれ、関数型プログラミングの別の用語です。プリペンドを介してList別のものから新しいものを作成する場合、演算子を使用してそれを行うことができます。List::
例:
val oldList = List(1, 2, 3)
val newList = 0 :: oldList // newList == List(0, 1, 2, 3)
Scala では、a で終わる演算子:は実際には右辺のメソッドなので0 :: oldList、oldList.::(0)- は0 :: oldList読みやすくするための構文糖衣です。
oldList次のように定義できました
val oldList = 1 :: 2 :: 3 :: Nil
whereNilは空の を表しますList。これをいくつかのステップに分けます:
3 :: NilList(3)が最初に評価され、ヘッド 3 と空のテールを持つa に相当するものが作成されます。List(3)。List(2, 3)。の結果ListがList(1, 2, 3)に割り当てられval oldListます。
::パターン マッチを使用する場合List、上記の作成方法と逆のように、基本的に a を頭と尾に分解しListます。するときはこちら
l match {
case h :: t => ...
}
l可能であれば、頭と尾に分解すると言っています。分解に成功したら、これらhとt変数を使用して、好きなことを行うことができます。通常は、 act on のようなことを行いh、再帰関数を on で呼び出しますt。
ここで注意すべきことの 1 つは、コードがコンパイルされないことです。実行しますがif (h > n) 0、明示的なelseものがないため、コードはコンパイラに対して次のように見えます。
if (h > n) 0
else { }
タイプAnyVal(0と「何もない」の共通のスーパータイプ)を持ち、保証に違反します-何らかの失敗値または何かを含むブランチIntを追加する必要があります。else
2 番目case _ =>は の のようなものdefaultでswitch、最初の でヘッド/テール分解に失敗したものをすべてキャッチしますcase。
あなたのコードは基本的にこれを行います:
l Listパラメータを取得して、頭と尾に分解できるかどうかを確認します。n。より大きい場合n、関数は 0 を返します (大きくない場合に何が起こるかを追加する必要があります)。これをパターン マッチングと呼びます。ステートメントのようなものswitchですが、より強力です。
役立つリソース:
http://www.scala-lang.org/node/120
http://www.codecommit.com/blog/scala/scala-for-Java-refugees-part-4