scala:pimp我的库有重载

时间:2010-12-18 21:27:09

标签: scala implicit

任何想法为什么没有以下工作?

implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs)
class ListExtensions[A](xs : List[A])
{
    def foreach[B](f: (A, Int) => B)
    {
        var i = 0;
        for (el <- xs)
        {
            f(el, i);
            i += 1;
        }
    }
}

var a = List(1, 2, 3);
a foreach { (el, i) => println(el, i) };

当我用fsc 2.8.1编译它时,我得到以下错误:“错误的参数数量;期望= 1:foreach {(el,i)=&gt; println(el,i)};”。我做错了什么或者根本没有办法通过“皮条客我的图书馆”技巧添加重载方法?

P.S。我不知道如何实现foreach的iterate-with-current-index风格(我知道zipWithIndex方法),而是关于重载和隐式转换如何一起使用。

3 个答案:

答案 0 :(得分:10)

编译器从不尝试使用隐式转换,因为List上已有foreach方法。更具体地说,Scala语言规范(http://www.scala-lang.org/docu/files/ScalaReference.pdf)的第7.3节规定在两种情况下应用隐式转换,第二种情况与示例相关:

  

如果选择器m不表示T的成员,则选择e.m,其中e为T类型。

顺便说一下,你可以使用zipWithIndex方法完成索引的foreach。

scala> val a = List("Java", "Scala", "Groovy")
a: List[java.lang.String] = List(Java, Scala, Groovy)

scala> a.zipWithIndex.foreach { case (el, idx) => println(el + " at index " + idx) } 
Java at index 0
Scala at index 1
Groovy at index 2

答案 1 :(得分:1)

只有当您尝试使用源类型中不存在的方法时,才会启用隐式转换。

在这种情况下,List有一个foreach方法,因此不会考虑转换。但是如果不匹配预期的签名,您将收到错误。

答案 2 :(得分:1)

(a : ListExtensions[Int]) foreach { (el, i) => println(el, i) };

或者,将名称更改为foreachWithIndex