2013-03-15 65 views
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,其中有一個適用的方法。這解釋了它是如何工作的,但沒有解釋WrappedString如何被接受到A => B類型的參數中(如在scaladoc中指定的那樣)。有人能解釋一下,請問這是怎麼發生的?

回答

7

截至collection.Seq[Char]方式,這是PartialFunction[Int, Char]一個亞型,這是Int => Char子類型:

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

所以,只有一個隱式轉換髮生的事情,原來String => WrappedString,該踢,因爲我們正在處理一個像函數一樣的字符串。

+0

好,我知道了。謝謝。 – folone 2013-03-15 13:30:15

4

由於WrappedString具有作爲超類型(Int) => Char

Scaladoc和展開 '線性超型' 部分。

+0

我沒注意到。謝謝。 – folone 2013-03-15 13:31:05

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) 
+0

'List(1,2,3)map「somestring」'更短:有時Scala不要求將方法調用和包裝參數放在花括號中:-) – 2013-03-15 13:39:43