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

WrappedStringapply メソッドを持つ に変換されるようです。これは、それがどのように機能するかを説明しWrappedStringますが、型のパラメーターに がどのように受け入れられたか ( scaladocA => Bで指定されているとおり) は説明しません。誰かが説明できますか、これがどのように起こるか教えてください。

4

3 に答える 3

7

としてcollection.Seq[Char]、のサブタイプでありPartialFunction[Int, Char]、のサブタイプですInt => Char

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

したがって、発生する暗黙の変換は1つだけです。元の変換String => WrappedStringは、文字列を関数のように扱っているために開始されます。

于 2013-03-15T13:27:45.783 に答える
4

WrappedStringスーパータイプとして持っているため(Int) => Char

Scaladocを開き、「線形スーパータイプ」セクションを展開します。

于 2013-03-15T13:27:53.330 に答える
2

他の人は、あなたの String が 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) 
于 2013-03-15T13:34:55.487 に答える