【Scale】パターンマッチングとサンプルクラス
10618 ワード
パターンマッチング
パターンマッチング(pattern-matching)を理解するには、まずこの2つの単語を分解し、パターン(pattern)とは何かを理解し、ここでのパターンはデータ構造上であり、このパターンは構造の構成を記述するために使用される.
「正規表現」のパターンを連想しやすいです.いいですね.このpatternは正規表現のpatternと似ていますが、適用範囲はもっと広く、さまざまなタイプのデータ構造に対して、正規表現ではなく文字列に対してのみ使用できます.例えば、正規表現の「^A.*」というpatternは、Aの先頭、後続の1つ以上の文字からなる文字列を表す.List(「A」,,*)もpatternであり、最初の要素が「A」であり、後続の1つ以上の要素のListであることを示す.
match式の違い
match式はJavaスタイルswitchの汎化と見なすことができる.各モードが定数であり、最後のモードが共通である場合、Javaスタイルのswitchは自然にmatch式として表現することができる.しかし、3つの違いを覚えておく必要があります.
パターンの種類
1、スルーモード()任意のオブジェクトを一致させ、デフォルトの「全一致(catch-all)」の予備オプション2として使用され、定数モデルは自身のみを一致させ、任意の字面量は定数3として使用でき、変数モードはワイルドカードモードと類似しており、任意のオブジェクトを一致させることができる.ワイルドカード()違いは、Scalaが変数を一致するオブジェクトにバインドすることです.
4、コンストラクタモードは深さマッチング(deep match)を提供し、準備オプションがサンプルクラスである場合、コンストラクタモードはまずオブジェクトがその準備オプションのサンプルクラスインスタンスであるかどうかを検査し、次にオブジェクトのコンストラクタパラメータが追加の提供モードに合致しているかどうかを検査する.コンストラクタモードでは、最上位オブジェクトが一致しているかどうかだけでなく、オブジェクトの内容が内層のモードに一致しているかどうかもチェックされます.追加のモード自体がコンストラクタモードを形成できるため、オブジェクト内部の任意の深さをチェックすることができます.
5、シーケンスパターンは、リストやArrayのようなシーケンスタイプにマッチングサンプルクラスのようにマッチングすることができる.
6、タプルモードマッチングタプル7、タイプモードはタイプテストとタイプ変換の簡単な代替とすることができる.
サンプルクラスサンプルクラスには、クラス名と一致するファクトリメソッドが追加されます.newキーワードを使わずにこのクラスを作成できます. サンプルクラスパラメータリストのすべてのパラメータは、val接頭辞を暗黙的に取得するため、フィールドとして維持される. コンパイラは、サンプルクラスにメソッドtoString、hashCode、およびequalsの実装を追加した.
これらの利便性の代価は、
クラスを閉じる
閉じたクラスは、クラス定義が存在するファイル以外に新しいサブクラスを追加することはできません.パターンマッチングに使用されるもう一つの役割は、サンプルクラスでパターンマッチングを行う場合、コンパイラに可能なすべての選択がリストされていることを確認してもらいたいということです.この目的を達成するには、サンプルクラスの汎用スーパークラスを
コンパイラが警告メッセージを行わないようにするには、一致するセレクタ式に
Optionタイプ
標準クラスライブラリのOptionタイプは、存在する可能性があり、存在しない可能性のある値をサンプルクラスで表します.Some(value)の形式であってもよく、valueは実際の値である.欠落した値を表すNoneオブジェクトであってもよい.Scalaコレクションクラスのいくつかの標準操作により、オプション値が生成されます.たとえばScalaのMapのgetメソッドでは,指定キーが見つかった場合にSome(value)が生成され,指定キーが見つからない場合にNoneが生成される.例を次に示します.
サンプルクラスNoneの形式は、nullを使用して値が欠けていることを示すよりも、空の文字列の意図よりも明確です.Optionは汎用型をサポートします.例えば、Some(Paris)のタイプはOption[String]である.
オプション値を分離する最も一般的な方法は、次のようにパターンマッチングによって行われます.
Scalaは、値がオプションであることを示すためにOptionの使用を奨励する.このオプション値を処理する方法にはJavaを超えるいくつかの利点がある.
参考資料
ところでパターンマッチング(1):パターンとは何ですか.
転載は作者Jason Dingとその出所GitCafeブログホームページを明記してください(http://jasonding1354.gitcafe.io/)Githubブログホームページ(http://jasonding1354.github.io/)CSDNブログ(http://blog.csdn.net/jasonding1354)簡書ホームページ(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)Google検索jasonding 1354私のブログのホームページに入ります
パターンマッチング(pattern-matching)を理解するには、まずこの2つの単語を分解し、パターン(pattern)とは何かを理解し、ここでのパターンはデータ構造上であり、このパターンは構造の構成を記述するために使用される.
「正規表現」のパターンを連想しやすいです.いいですね.このpatternは正規表現のpatternと似ていますが、適用範囲はもっと広く、さまざまなタイプのデータ構造に対して、正規表現ではなく文字列に対してのみ使用できます.例えば、正規表現の「^A.*」というpatternは、Aの先頭、後続の1つ以上の文字からなる文字列を表す.List(「A」,,*)もpatternであり、最初の要素が「A」であり、後続の1つ以上の要素のListであることを示す.
match式の違い
match式はJavaスタイルswitchの汎化と見なすことができる.各モードが定数であり、最後のモードが共通である場合、Javaスタイルのswitchは自然にmatch式として表現することができる.しかし、3つの違いを覚えておく必要があります.
1. match , Scala
2. Scala 。 C C , break switch。
3. ,MatchError 。 ,
パターンの種類
1、スルーモード()任意のオブジェクトを一致させ、デフォルトの「全一致(catch-all)」の予備オプション2として使用され、定数モデルは自身のみを一致させ、任意の字面量は定数3として使用でき、変数モードはワイルドカードモードと類似しており、任意のオブジェクトを一致させることができる.ワイルドカード()違いは、Scalaが変数を一致するオブジェクトにバインドすることです.
// , expr
//somethingElse expr, expr
expr match {
case 0 => "zero"
case somethingElse => "not zero: " + somethingElse
}
4、コンストラクタモードは深さマッチング(deep match)を提供し、準備オプションがサンプルクラスである場合、コンストラクタモードはまずオブジェクトがその準備オプションのサンプルクラスインスタンスであるかどうかを検査し、次にオブジェクトのコンストラクタパラメータが追加の提供モードに合致しているかどうかを検査する.コンストラクタモードでは、最上位オブジェクトが一致しているかどうかだけでなく、オブジェクトの内容が内層のモードに一致しているかどうかもチェックされます.追加のモード自体がコンストラクタモードを形成できるため、オブジェクト内部の任意の深さをチェックすることができます.
// ,
abstract class Item
case class Product(description: String, price: Double) extends Item
case class Bundle(description: String, discount: Double, items: Item*) extends Item
def price(it: Item): Double = it match {
case Product(_, p) => p
case Bundle(_, disc, its @ _*) => its.map(price _).sum * (100-disc) /100
// @ its
}
//
val bun1 = Bundle("Father's day special", 20.0, Product("Massager", 188.0))
val bun2 = Bundle("Appliances on sale", 10.0, Product("Haier Refrigerato, 3000.0), Product("Geli air conditionor",2000.0)) // 1 scala> price(bun1) res5: Double = 150.4 // 2 scala> price(bun2) res6: Double = 4500.0
5、シーケンスパターンは、リストやArrayのようなシーケンスタイプにマッチングサンプルクラスのようにマッチングすることができる.
expr match {
case List(0, _, _) => println("found it")
case _ =>
}
//
expr match {
case List(0, _*) => println("found it")
case _ =>
}
6、タプルモードマッチングタプル7、タイプモードはタイプテストとタイプ変換の簡単な代替とすることができる.
scala> def generalSize(x: Any) = x match {
| case s: String => s.length
| case m: Map[_, _] => m.size
| case _ => 1
| }
generalSize: (x: Any)Int
scala> generalSize("abc")
res7: Int = 3
scala> generalSize(Map(1 -> 'a', 2 -> 'b'))
res8: Int = 2
scala> generalSize(Math.PI)
res9: Int = 1
サンプルクラス
case
修飾子を有するクラスをサンプルクラス(case class)と呼ぶ.この修飾子は、Scalaコンパイラが自動的にクラスに文法的な利便性を追加することができます.これらの利便性の代価は、
case
修飾子を書かなければならず、サンプルクラスおよびオブジェクトは、追加の方法および各コンストラクタパラメータに暗黙のフィールドを追加することによって大きくなることである.サンプルクラスは、モードマッチングに最適化された特殊なクラスです.クラスを閉じる
閉じたクラスは、クラス定義が存在するファイル以外に新しいサブクラスを追加することはできません.パターンマッチングに使用されるもう一つの役割は、サンプルクラスでパターンマッチングを行う場合、コンパイラに可能なすべての選択がリストされていることを確認してもらいたいということです.この目的を達成するには、サンプルクラスの汎用スーパークラスを
sealed
と宣言する必要があります.閉じたクラスから継承されたサンプルクラスをマッチングすると、コンパイラは警告情報を通知することによって欠落したモードの組合せを識別します.例を挙げます.sealed abstract class Amount
case class Dollar(value: Double) extends Amount
case class Euro(value: Double) extends Amount
case class Currency(value: Double, unit: String) extends Amount
def describe(a: Amount): String = a match {
case Dollar(_) => "Dollar"
case Euro(_) => "Euro"
}
//
//warning: match may not be exhaustive.
//It would fail on the following input: Currency(_, _)
// def describe(a: Amount): String = a match {
// ^
//describe: (a: Amount)String
コンパイラが警告メッセージを行わないようにするには、一致するセレクタ式に
@unchecked
注記を追加する必要があります.このようにdef describe(a: Amount): String = (a: @unchecked) match {
です.クラスが閉じている場合、コンパイラのすべてのサブクラスが知られているため、コンパイラはモード文の整合性をチェックすることができます.すべての(同じグループ)サンプルクラスを閉じたクラスまたは特質に拡張するのは良い方法です.Optionタイプ
標準クラスライブラリのOptionタイプは、存在する可能性があり、存在しない可能性のある値をサンプルクラスで表します.Some(value)の形式であってもよく、valueは実際の値である.欠落した値を表すNoneオブジェクトであってもよい.Scalaコレクションクラスのいくつかの標準操作により、オプション値が生成されます.たとえばScalaのMapのgetメソッドでは,指定キーが見つかった場合にSome(value)が生成され,指定キーが見つからない場合にNoneが生成される.例を次に示します.
scala> val capitals = Map("France" -> "Paris",
| "Japan" -> "Tokyo", "China" -> "Beijing")
capitals: scala.collection.immutable.Map[String,String] = Map(France -> Paris, Japan -> Tokyo, China -> Beijing)
scala> capitals get "France"
res2: Option[String] = Some(Paris)
scala> capitals get "North Pole"
res3: Option[String] = None
サンプルクラスNoneの形式は、nullを使用して値が欠けていることを示すよりも、空の文字列の意図よりも明確です.Optionは汎用型をサポートします.例えば、Some(Paris)のタイプはOption[String]である.
オプション値を分離する最も一般的な方法は、次のようにパターンマッチングによって行われます.
scala> def showCapital(x: Option[String]) = x match {
| case Some(s) => s
| case None => "?"
| }
showCapital: (x: Option[String])String
scala> showCapital(capitals get "Japan")
res5: String = Tokyo
scala> showCapital(capitals get "France")
res6: String = Paris
scala> showCapital(capitals get "China")
res7: String = Beijing
scala> showCapital(capitals get "North Pole")
res8: String = ?
Scalaは、値がオプションであることを示すためにOptionの使用を奨励する.このオプション値を処理する方法にはJavaを超えるいくつかの利点がある.
Option[String] String, String null
null null Scala , Option[String] , String , 。
参考資料
ところでパターンマッチング(1):パターンとは何ですか.
転載は作者Jason Dingとその出所GitCafeブログホームページを明記してください(http://jasonding1354.gitcafe.io/)Githubブログホームページ(http://jasonding1354.github.io/)CSDNブログ(http://blog.csdn.net/jasonding1354)簡書ホームページ(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)Google検索jasonding 1354私のブログのホームページに入ります