为什么我的对象不是包<root>的成员,如果它在一个单独的源文件中?

Mar*_*lty 19 scala packages

我在访问根包中定义的对象时遇到问题.如果我将所有代码都放在一个文件中,它可以正常工作,但是当我将它分成两个文件时,我无法通过编译器.

这很好用:

所有在一个文件中称为packages.scala:

object Foo
  val name = "Brian"
}

package somepackage {
  object Test extends App {
    println(Foo.name)
  }
}
Run Code Online (Sandbox Code Playgroud)

见证人:

$ scalac packages.scala
$ scala -cp . somepackage.Test
Brian
Run Code Online (Sandbox Code Playgroud)

但是如果我将代码分成两个文件:

packages.scala

object Foo {
  val name = "Brian"
}
Run Code Online (Sandbox Code Playgroud)

packages2.scala

package somepackage {
  object Test extends App {
    println(Foo.name)
  }
}
Run Code Online (Sandbox Code Playgroud)

一切都失败了:

$ scalac packages.scala packages2.scala
packages2.scala:3: error: not found: value Foo
Run Code Online (Sandbox Code Playgroud)

所以我尝试引用Foo绝对:

...
    println(_root_.Foo.name)
...
Run Code Online (Sandbox Code Playgroud)

但这也不起作用:

$ scalac packages.scala packages2.scala
packages2.scala:3: error: object Foo is not a member of package <root>
Run Code Online (Sandbox Code Playgroud)

如果Foo不是根包的成员,在地球上它?

Deb*_*ski 28

我认为这是规范中的相关部分:

假设包装外的顶级定义被注入特殊的空包中.该包无法命名,因此无法导入.但是,空包的成员彼此可见而没有资格.

Scala参考§9.2包.

但是,如果您有以下内容,请不要问我为什么会有效packages2.scala:

object Dummy

package somepackage {
  object Test extends App {
    println(Foo.name)
  }
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*ell 20

Foo是root包的成员,但你不能引用它.这是JVM语言的通用内容(请参阅如何在默认包中访问java-classes?对于Groovy,在Java中使用默认包导入类的语法是什么?).对于Scala来说也是如此.

从Java答案:

您无法从默认包中导入类.除了非常小的示例程序之外,您应该避免使用默认包.

从Java语言规范:

从未命名的包导入类型是编译时错误.

它在一个文件中工作的原因是因为编译器可以立即使用所有内容,编译器会对此进行处理.我怀疑这是允许脚本编写的.

故事的道德:如果你没有编写脚本,请不要使用默认包.