私は興味があります-のメソッドのU
宣言におけるジェネリック型のポイントは何ですか?Traversable
foreach
def foreach[U](f: A => U): Unit
の戻り型Function1
は共変であるため、なぜそれだけではいけないのでしょうか。
def foreach(f: A => Any): Unit
?
マーティン・オーダスキーではないので、推測することしかできません:-)のスカラドックを見ると、次のforeach
ことがわかります。
/** Applies a function `f` to all elements of this $coll.
*
* @param f the function that is applied for its side-effect to every element.
* The result of function `f` is discarded.
*
* @tparam U the type parameter describing the result of function `f`.
* This result will always be ignored. Typically `U` is `Unit`,
* but this is not necessary.
*
* @usecase def foreach(f: A => Unit): Unit
*/
したがって、の戻りタイプは重要でf
はなく、その結果は常に破棄されます。これは、私にとって、ここでジェネリック型パラメーターを使用して戻り型をマークすることは、「戻り型は何でも、本当に何でもかまいません」と言って、単なるドキュメントの微妙なことであることを示唆しています。の戻り型はAny
、(一部の)読者に、ここで適用可能な関数型に対するある種の制限を示唆する場合があります。
もう1つの側面は、Scalaがゼロからジェネリックになるように非常に意識的に設計されていることです。したがって、私にとって、ここでジェネリック型パラメーターを使用することは、言語の一般的な哲学と一致しますがAny
、技術的には使用可能ですが、使用することは、他の言語とは相容れない、明らかに非ジェネリックなアプローチになります。
から継承し、からのTraversable
戻り値を使用できるようにするためでしょうか。U
f: A => U
trait TraversableWithHandler[+A, E <: Option[Throwable]] extends Traversable[A] {
override def foreach[U](f: A => U): Unit
def handleError(t: E)
}
たとえば では、 from insidejQuery
の戻り値はと同等であり、異なる値は.false
foreach
break
continue
使用事例
breakable {
List(1,2,3).foreach(_ match {
case 1 => println("ok")
case 2 =>
println("Sort of, soft interrupt?")
return false
case 3 => break
})
}
次のコード (並列) が壊れることはないため (この場合、スタックレスのスロー可能なソリューションは理想的ではないようです):
import scala.util.control.Breaks._
breakable {
(0 to 100).toList.par.foreach(_ match {
case n if (n <= 50) =>
println("#" * 100)
try { break } catch {
case t: Throwable => println("" + t); break
}
case n if (n > 50) =>
println("" + n)
case _ => "ok"
})
}