2010-12-18 78 views
2

任何想法为什么以下不工作?scala:皮条客我的图书馆有超载

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)=>的println(EL,I)} ;”。我做错了什么或者根本没有办法通过“pimp my library”技巧来添加重载方法?

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

+0

可能重复(http://stackoverflow.com/questions/4443783/overriding-arithmetic-operators-on -INT-经由隐-转化) – 2010-12-19 09:20:10

回答

10

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

In a selection e.m with e of type T, if the selector m does not denote a member of 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

隐式转换只会在尝试使用源类型中不存在的方法时触发。

在这种情况下,List有一个foreach方法,所以不会考虑转换。但是你会因为不符合预期的签名而出错。

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

或者,将名称改为foreachWithIndex [经由隐式转换的诠释重写算术运算符]的