foreach中泛型类型的重点是什么?

时间:2012-12-30 20:44:18

标签: scala generics types foreach

我很好奇 - U Traversable方法声明中泛型类型foreach的重点是什么?

def foreach[U](f: A => U): Unit

由于Function1的返回类型是协变的,为什么不能只是:

def foreach(f: A => Any): Unit

2 个答案:

答案 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" 
  }) 
}
相关问题