【问题标题】:scala: pimp my library with overloadsscala:用重载皮条客我的图书馆
【发布时间】:2011-05-27 16:28:03
【问题描述】:

任何想法为什么以下不起作用?

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: a foreach { (el, i) => println(el, i) };”。我是做错了什么,还是根本没有办法通过“pimp my library”技巧来添加重载方法?

附:我想知道的不是实现 foreach 的 iterate-with-current-index 风格(我知道 zipWithIndex 方法),而是想知道重载和隐式转换如何一起发挥作用。

【问题讨论】:

标签: scala implicit


【解决方案1】:

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

在类型为 T 的 e 的选择 e.m 中,如果选择器 m 不表示 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

【讨论】:

    【解决方案2】:

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

    在这种情况下,List 有一个 foreach 方法,因此不会考虑转换。但是你会因为不匹配预期的签名而得到一个错误。

    【讨论】:

      【解决方案3】:
      (a : ListExtensions[Int]) foreach { (el, i) => println(el, i) };
      

      或者,将名称更改为 foreachWithIndex

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-01
        • 2016-02-05
        • 2020-02-22
        • 1970-01-01
        • 2015-11-24
        相关资源
        最近更新 更多