斯卡拉福利局...我很困惑Scala的陣列VS載體
object myApp extends App {
println("Echo" + (args mkString " "))
}
「ARGS」 的類型是陣列[字符串],但在scaladoc,陣列有沒有這樣的方法。 mkString是Vector的一種方法,但是我沒有看到兩者之間的任何繼承關係。那麼爲什麼我們可以在參數上使用mkString方法呢?
斯卡拉福利局...我很困惑Scala的陣列VS載體
object myApp extends App {
println("Echo" + (args mkString " "))
}
「ARGS」 的類型是陣列[字符串],但在scaladoc,陣列有沒有這樣的方法。 mkString是Vector的一種方法,但是我沒有看到兩者之間的任何繼承關係。那麼爲什麼我們可以在參數上使用mkString方法呢?
我不是一個scala專家(遠離它!),但我認爲答案是隱式轉換(請參閱scala.Predef
)和WrappedArray.scala。
特別地,PREDEF具有如下的隱式轉換:
implicit def genericWrapArray [T] (xs: Array[T]): WrappedArray[T]
而且WrappedArray具有mkString方法。當scala在Array上找不到mkString方法時,它會查找到一個類型的隱式轉換。
http://www.scala-lang.org/api/current/scala/Predef $ html的
http://www.scala-lang.org/api/current/scala/collection/mutable/WrappedArray.html
擴大對凱文的回答,並解釋爲什麼它是不可能的scaladoc告訴你什麼存在隱式轉換:隱式轉換纔開始發揮作用時,你的代碼不會否則編譯。
您可以將其視爲編譯期間激活的類型錯誤的錯誤恢復機制。在這種情況下,Array[String]
沒有mkString
方法。此代碼無法編譯,因爲Array[T]
上不存在該方法。但在放棄編譯器之前,會在範圍內尋找隱式轉換。
碰巧Predef
帶來了一些隱式轉換的範圍和一個將在這裏適用。
通過使用-Xprint:typer
標誌進行編譯,可以確定應用哪種隱式轉換。在這種情況下,它將打印:
$ scalac -d classes -Xprint:typer A.scala
[[syntax trees at end of typer]]// Scala source: A.scala
package <empty> {
final object myApp extends java.lang.Object with App with ScalaObject {
def this(): object myApp = {
myApp.super.this();
()
};
scala.this.Predef.println("Echo ".+(scala.this.Predef.refArrayOps[String](myApp.this.args).mkString(" ")))
}
}
因此,您可以看到Predef.refArrayOps
實際上是隱式轉換。它將您的陣列轉換爲ArrayOps[String]
,它的確有mkString
method。
因此,考慮到這一點,您可以看到爲什麼scaladoc對於Array
無法告訴您可以應用哪些隱式轉換。它可能是任何東西。事實上,這完全是基於沒有這種方法的事實。只有編譯器會根據代碼知道它隱含的內容。
你甚至可以定義自己的隱式轉換:
object myApp extends App {
implicit def myImplicit(arr:Array[String]) = new {
def mkString(s:String) = arr.length + s
}
println("Echo " + (args mkString(" ")))
}
這將帶來以下影響:
$ scala -cp classes myApp a b c
Echo 3
顯然scaladoc將無法證明。請注意,Eclipse Scala插件可以通過按F3(最終會在TraversableOnce
中)實現mkString
。
感謝您的詳細解釋:) – 2011-05-26 04:38:35
但是Scaladoc至少可以說Predef(這很特別,因爲它總是在範圍內)具有從Array的隱式轉換。這將是有益的。
謝謝,我沒有隱式轉換的負責人。 WrappedArray和Vector都從它們共享的TraversableOnce特徵中獲取mkString方法。如果scaladoc在類的定義中告訴你隱含的defs存在,可能會有用嗎? – 2011-05-25 23:14:29