什么是Scala doc中的"Shadowed Implicit Value Members"?

Xin*_*ang 5 scala

StringOps doc中有一个Shadowed Implicit Value Members部分.例如:

def split(arg0:String,arg1:Int):Array [String]

隐式信息
此成员是通过scala.Predef中的方法unaugmentString执行的从StringOps到String的隐式转换添加的.

阴影
此隐式继承的成员由此类中的一个或多个成员遮蔽.要访问此成员,您可以使用类型归属:

(stringOps: String).split(arg0, arg1)
Run Code Online (Sandbox Code Playgroud)

定义类
字符串

但是当我尝试运行以下程序时:

"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函数签名是不同的,所以不需要"类型归属".

这是"暗影隐含价值成员"所代表的吗?我有点困惑.谢谢!

the*_*eon 6

通常,当您调用给定类型不存在的方法时,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)

试试吧

也许只是文档中的错误.