Scala奇怪的map函数行为

3
为什么以下代码可以工作?
scala> List(1,2,3) map "somestring"
res0: List[Char] = List(o, m, e)

它可以在2.9和2.10版本中正常运行。 查看类型:

[master●●] % scala -Xprint:typer -e 'List(1,2,3) map "somestring"'                                                                                ~/home/folone/backend
[[syntax trees at end of                     typer]] // scalacmd2632231162205778968.scala
package <empty> {
  object Main extends scala.AnyRef {
    def <init>(): Main.type = {
      Main.super.<init>();
      ()
    };
    def main(argv: Array[String]): Unit = {
      val args: Array[String] = argv;
      {
        final class $anon extends scala.AnyRef {
          def <init>(): anonymous class $anon = {
            $anon.super.<init>();
            ()
          };
          immutable.this.List.apply[Int](1, 2, 3).map[Char, List[Char]](scala.this.Predef.wrapString("somestring"))(immutable.this.List.canBuildFrom[Char])
        };
        {
          new $anon();
          ()
        }
      }
    }
  }
}

看起来它被转换为WrappedString,该类具有一个apply方法。这解释了它的工作原理,但并没有解释一个WrappedString如何被接受为类型为A => B的参数(如在scaladoc中指定)。请问有人能解释一下这是怎么发生的吗?
3个回答

7

通过 collection.Seq[Char],它是 PartialFunction[Int, Char] 的子类型,而 PartialFunction[Int, Char]Int => Char 的子类型:

scala> implicitly[collection.immutable.WrappedString <:< (Int => Char)]
res0: <:<[scala.collection.immutable.WrappedString,Int => Char] = <function1>

因此只有一个隐式转换发生——原始的String => WrappedString,因为我们把字符串当作函数来处理。


4

由于WrappedString的超类型为(Int) => Char

Scaladoc并展开“线性超类型”部分。


我没有注意到那个。谢谢。 - George

2

其他人已经明确表示,你的字符串实现了一个接受Int并返回char的函数(这是Int=>Char符号)。 这允许像这样的代码:

scala> "Word".apply(3)
res3: Char = d

扩展您的示例将使其更清晰,也许:

List(1,2,3).map(index => "somestring".apply(index))
List(1,2,3).map(index => "somestring"(index)) //(shorter, Scala doesn't require the apply)
List(1,2,3).map("somestring"(_)) //(shorter, Scala doesn't require you to name the value passed in to map) 
List(1,2,3).map("somestring") //(shorter, Scala doesn't require you to explicitly pass the argmument if you give it a single-arg function) 

List(1,2,3) map "somestring" 简写:有时 Scala 不需要您在方法调用中加点号,并将参数包装在大括号中 :-) - om-nom-nom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接