StringOps doc中有一个Shadowed Implicit Value Members部分.例如:
def split(arg0:String,arg1:Int):Array [String]
隐式信息
此成员是通过scala.Predef中的方法unaugmentString执行的从StringOps到String的隐式转换添加的.阴影
此隐式继承的成员由此类中的一个或多个成员遮蔽.要访问此成员,您可以使用类型归属:Run Code Online (Sandbox Code Playgroud)(stringOps: String).split(arg0, arg1)定义类
字符串
但是当我尝试运行以下程序时:
"aaa bbb ccc".split(" ", 2) //> res0: Array[String] = Array(aaa, bbb ccc)
调用String.split(arg0: String, arg1: Int)不需要使用类型描述文档中描述的类型.
那么Shadowed Implicit Value会员指的是什么?我试过问谷歌但找不到任何参考.
是这样的:
class A {
def foo() = println("foo")
}
class AOps(a: A) {
def bar() = println("bar")
def foo() = println("new foo")
def foo(i: Int) = println("foo %d".format(i))
}
object Program {
implicit def A2AOps(a: A) = new AOps(a) //> A2AOps: (a: A)AOps
val a = new A() //> a : A = A@15669ae
a.foo //> foo
a.bar //> bar
(a: AOps).foo //> new foo
a.foo(1) //> foo 1
}
Run Code Online (Sandbox Code Playgroud)
那么String.split(...)和StringOps.split函数签名是不同的,所以不需要"类型归属".
这是"暗影隐含价值成员"所代表的吗?我有点困惑.谢谢!
通常,当您调用给定类型不存在的方法时,Scala编译器将执行隐式转换:
case class Foo(x :String)
implicit class Bar(foo: Foo) {
def barOnly = "w00p"
}
println( Foo("test").barOnly )
Run Code Online (Sandbox Code Playgroud)
这里当我们在scala编译器的barOnly一个实例上调用该方法时,Foo可以看到它需要进行隐式转换Foo,Bar以便为我们提供该方法,并获得预期的输出w00p.试试吧
但是,如果在Foo和中存在具有相同签名的方法Bar,那么我们会有一些阴影,并且scala编译器不会执行隐式转换,除非我们明确要求使用类型ascription:
case class Foo(x :String) {
def whoAmI = "Foo: " + x
}
implicit class Bar(foo: Foo) {
def whoAmI = "Bar: " + foo.x
}
println( Foo("test").whoAmI )
println( (Foo("test"): Bar).whoAmI )
Run Code Online (Sandbox Code Playgroud)
输出是:
Foo: test
Bar: test
Run Code Online (Sandbox Code Playgroud)
在您的例子split在scaladocs,也有称为方法split上都String和StringOps,但他们采取不同的参数类型,所以我不完全知道为什么医生现在都警告我们不必使用类型归属.在这种情况下,我们不需要为编译器消除任何歧义,并且类型ascription无效:
import scala.collection.immutable.StringOps
val stringOps: StringOps = "aaa bbb ccc"
println( stringOps.split("a", 2).mkString )
println( (stringOps: String).split("a", 2).mkString )
Run Code Online (Sandbox Code Playgroud)
这两行的输出完全相同:
aa bbb ccc
aa bbb ccc
Run Code Online (Sandbox Code Playgroud)
也许只是文档中的错误.