我很好奇 - U
Traversable
方法声明中泛型类型foreach
的重点是什么?
def foreach[U](f: A => U): Unit
由于Function1
的返回类型是协变的,为什么不能只是:
def foreach(f: A => Any): Unit
答案 0 :(得分:9)
不是马丁奥德斯基,我只能猜测:-)看看foreach
的Scaladoc,我看到了:
/** 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
的返回类型可能会向(某些)读者建议对此处适用的函数类型的某种限制。
另一个方面是Scala非常有意识地从头开始设计为通用的。所以 - 对我来说 - 在这里使用泛型类型参数与语言的一般哲学是一致的,而使用Any
- 尽管在技术上可用 - 将是一种绝对非通用的方法,与其他方法不一致语言。
答案 1 :(得分:-5)
也许允许您从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)
}
例如,在jQuery
中,从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"
})
}