1

FirstSecondは同じように見えますが、なぜですか?

初め

val iter = List(1, 2, 3, 4, 5).iterator
val first = iter.collect(new PartialFunction[Int, Int]{
  def apply(i: Int) = i
  def isDefinedAt(i: Int) = i > 0 && i < 3
})
first.foreach((println(_)))

2番

val iter2 = List(1, 2, 3, 4, 5).iterator
val second = iter2.collect {
  case i:Int if i > 0 && i < 3 => i
}
second.foreach((println(_)))

Scala コンパイラ が部分からの生成でFirst{ case i:Int if i > 0 && i < 3 => i } の実装形式に自動的に変換するためでしょうか。isDefinedAtif i > 0 && i < 3

また、case i:Int if i > 0 && i < 3 => i私が正しければ、Case クラスのパターン マッチングです。ただし、scala/src/library/scala/PartialFunction.scalaには、 の Case クラス定義はありませんPartialFunction

trait PartialFunction[-A, +B] extends (A => B)

では、なぜこのケース クラス パターン マッチが機能するのでしょうか。

Scala コンパイラーは多くの暗黙的な作業をインテリジェントに行うと思いますが、何が起こっているのか、Scala コードの書き方を理解するのに混乱しています。

言語やコンパイラの仕様ではなく、Scala コードの構文と Scala のコードの書き方を理解するための参考文献があれば、提案してください。

4

3 に答える 3

2

はい、コンパイラは 2 番目のバージョンを に変換しますPartialFunction[Int,Int](それが必要なためcollect)。

ここではcase class一致はありません。また、値が一致する必要があるため、型の一致すらありませんInt(したがって、2 番目のバージョンの型宣言は必要ありません)。

スタイル ガイドには、Scala の一般的な記述方法に関するヒントが多数記載されています。

于 2019-11-16T12:25:10.093 に答える
2

Scala コンパイラが自動的に { case i:Int if i > 0 && i < 3 => i } を First の実装形式に変換し、 **if i > 0 && i < 3 ** の部分から isDefinedAt を生成するためでしょうか?

はい、正確な翻訳はPattern Matching Anonymous Functionsに記載されています。こちらになります

new PartialFunction[Int, Int]{
  def apply(x: Int) = x match {
    case i:Int if i > 0 && i < 3 => i
  }
  def isDefinedAt(x: Int) = x match {
    case i:Int if i > 0 && i < 3 => true
    case _ => false
  } 
}

の最初の例との違いに注意してくださいapply。が false の場合でも呼び出すことができます。isDefined

また、 case i:Int if i > 0 && i < 3 => i は Case クラスのパターン マッチングです。

どちらかといえば、それは逆です。ケース クラスはパターン マッチングが可能であり、パターン マッチングはcaseScala でキーワードを使用するため、そのように呼び出されます。

于 2019-11-16T12:25:48.187 に答える