scala:用重载来修饰我的库

发布于 2024-10-08 21:08:06 字数 627 浏览 0 评论 0原文

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

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) };”。我是否做错了什么,或者根本没有办法通过“拉皮条我的库”技巧来添加重载方法?

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

Any ideas why doesn't the following work?

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) };

When I compile this with fsc 2.8.1, I get the following error: "wrong number of parameters; expected = 1: a foreach { (el, i) => println(el, i) };". Am I doing something wrong or there simply ain't a way to add an overloaded method by the means of "pimp my library" trick?

P.S. I wonder not about implementing the iterate-with-current-index flavor of foreach (I'm aware of zipWithIndex method), but rather about how overloading and implicit conversions play together.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

简单气质女生网名 2024-10-15 21:08:06

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

在 e 类型为 T 的选择 em 中,如果选择器 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

The compiler never attempts to use the implicit conversion because there's already a foreach method on List. More specifically, section 7.3 of the Scala Language Specification (http://www.scala-lang.org/docu/files/ScalaReference.pdf) states that an implicit conversion is applied in two cases, with the second case relevant to the example:

In a selection e.m with e of type T, if the selector m does not denote a member of T.

As an aside, you can accomplish a foreach with an index by using the zipWithIndex method.

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
半暖夏伤 2024-10-15 21:08:06

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

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

Implicit conversion will only kick in when you attempt to use a method that doesn't exist on the source type.

In this case, List has a foreach method, so no conversion will be considered. But you will get an error for not matching the expected signature.

过气美图社 2024-10-15 21:08:06
(a : ListExtensions[Int]) foreach { (el, i) => println(el, i) };

或者,将名称更改为 foreachWithIndex

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

Or, change the name to foreachWithIndex

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文