scala - Scala 文档中的 "Shadowed Implicit Value Members"是什么?

标签 scala

StringOps 中有一个隐藏的隐式值成员部分博士。例如。:

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

Implicit information
This member is added by an implicit conversion from StringOps to String performed by method unaugmentString in scala.Predef.

Shadowing
This implicitly inherited member is shadowed by one or more members in this class. To access this member you can use a type ascription:

(stringOps: String).split(arg0, arg1)

Definition Classes
String



但是当我尝试运行以下程序时:
"aaa bbb ccc".split(" ", 2) //> res0: Array[String] = Array(aaa, bbb ccc)
调用String.split(arg0: String, arg1: Int)不需要使用描述的文档中的类型归属。

那么Shadowed Implicit Value Members 指的是什么?我试图问谷歌,但找不到任何引用。

是不是像:
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
}

然后 String.split(...)StringOps.split函数签名不同,因此不需要“类型归属”。

这就是“Shadowed Implicit Value Members”的含义吗?我有点疑惑。谢谢!

最佳答案

通常,当您调用给定类型不存在的方法时,Scala 编译器会执行隐式转换:

case class Foo(x :String)

implicit class Bar(foo: Foo) {
  def barOnly = "w00p"
}

println( Foo("test").barOnly )

这里当我们调用方法barOnlyFoo 的实例上scala 编译器可以看到它需要从 Foo 进行隐式转换至Bar为我们提供该方法,我们得到 w00p 的预期输出. Try it

但是,如果 Foo 中存在具有相同签名的方法和 Bar ,那么我们有一些阴影,除非我们使用类型归属明确要求它,否则 scala 编译器不会进行隐式转换:
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 )

输出是:
Foo: test
Bar: test

Try it

在您的 split 示例中在 scaladocs 中,有一些方法叫做 split两个StringStringOps ,但是它们采用不同的参数类型,所以我不完全确定为什么文档警告我们必须使用类型归属。在这种情况下,我们不需要为编译器消除任何歧义,类型归属没有任何效果:
import scala.collection.immutable.StringOps

val stringOps: StringOps = "aaa bbb ccc"

println( stringOps.split("a", 2).mkString )
println( (stringOps: String).split("a", 2).mkString )

这两行的输出是相同的:
aa bbb ccc
aa bbb ccc

Try it

也许只是文档中的一个错误。

关于scala - Scala 文档中的 "Shadowed Implicit Value Members"是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19615810/

相关文章:

scala - 修改 Scala 中 (String, String) 变量的位置

scala - Spark 错误 : Not enough space to cache partition rdd_8_2 in memory! 可用内存为 58905314 字节

postgresql - 在带有 uuid_generate_v4() 的 postgres 上使用光滑代码生成器时出错

scala - 对 Scala 中重载方法的引用

scala - 为什么最好在函数参数中使用 case 来进行 map 函数中的模式匹配

由于 StaticLoggerBinder.class 中的重复数据删除错误,Scala SBT 程序集无法合并

scala - 是否可以在 Scala 宏中从 WeakTypeTag 生成 Apply?

json - Scala HTTP4s 打印整个 HTTP 错误响应

scala - 交叉联接运行时错误:使用CROSS JOIN语法允许这些关系之间的笛卡尔积

scala - 如何过滤解析器组合器中的保留字?