斯卡拉福利局...我很困惑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