为什么包对象隐式成员在某些情况下对子包可见?

时间:2017-09-20 10:14:04

标签: scala packages

让我们考虑以下包层次结构:

test
  --foo
    --Foo.scala
  --bar
    --Bar.scala
  package.scala

如果在test的包对象中有以下代码:

package object test {
    implicit class Pipe[A](a: A) {
      def |>[B](f: A => B): B = f(a)
    }
}

然后是Foo.scala中的案例类(在包test.foo中):

package test.foo

case class Foo(i: Int)

object Foo {
    2.0 |> math.floor // 1 - Does not compile, package object is not visible
}

最后包test.bar中的应用程序:

package test.bar

import test.foo.Foo

object Bar extends App {

    def plus2(i: Int) = i + 2
    def plus2(f: Foo) = f.i + 2
    def plus2(o: Option[Foo]) = o.map(f => Foo(f.i + 2))

    println(2 |> plus2) // 2 - Does not compile, package object is not visible
    println(Foo(2) |> plus2) // 3 - Does compile !?
    println(Option(Foo(2)) |> plus2) // 4 - Does compile too !?

}

前两条注释显示了不编译的行,这是预期的行为,因为包对象在任何子包中都不可见。

为什么第三个和第四个案例会编译?为什么在这些情况下应用隐式转换?我们没有使用根类的一个类(Foo在子包中,Option根本不在包中)我们也没有导入根包。

1 个答案:

答案 0 :(得分:0)

这是由package object中定义的暗示引起的,这些含义仅适用于以该包为前缀的类型。例如,类型为Foo

因此,对于您的问题,您可以手动导入隐含,例如:

import test._
println(2 |> plus2)
println(Foo(2) |> plus2)

了解更多:

  

请注意,包在内部表示为具有用于保存包成员的协同模块的类。因此,包对象中定义的implicits是该包前缀的类型的隐式范围的一部分。

http://www.scala-lang.org/files/archive/spec/2.12/07-implicits.html