在Scala中,您可以定义package objects。因此,您似乎可以通过编写包名称来访问该包对象,然后`package`
:
// file package.scala in src/com
package com
package object test {
val Version = 2
}
// file Test.scala in src/test
package test
object Test {
def main(args: Array[String]) {
val p = com.test.`package` // get ref on package object
val v1 = com.test.`package`.Version // (1) get val
val v2 = com.test.Version // (2) get val
}
}
(1)和(2)之间有什么区别?在某些情况下,我必须为我的代码编写额外的`package`
来运行。应该有区别还是编译器错误?
此外,例如,这一行的意思是Predef.scala
?
scala.`package` // to force scala package object to be seen.
答案 0 :(得分:4)
只是盲目猜测:行
scala.`package`
生成一个简单的getstatic
(包对象代码),后跟pop
。因此,如果之前尚未初始化包对象,那么它只会初始化它。
所以我的猜测是Predef.scala
你不能确定(或者可能确定它没有发生)包对象已经初始化了。大多数其他模块可能隐式依赖于Predef
被加载,因此这些模块不能盲目地初始化。因此,需要通过在Predef
中明确包含模块/包/对象来确保这一点。 List模块和StringBuilder也是如此。所以,它可能只是一个初始化订单。
答案 1 :(得分:3)
代码中的(1)和(2)之间没有区别。 包对象允许您将其写为(2)。但你仍然可以写作(1)。
我只能想象你必须在你的代码中编写package
的情况必须要对你的开发环境(Eclipse / Scala插件?)做些什么,期望一个名为“package”的类来源于名为“package.scala”的源而不是“test.scala”。
您是否可以重现 撰写package
的案例?
我也很好奇Predef中该行的效果。
答案 2 :(得分:2)
据我了解,包对象(在Scala 2.8中引入)意味着在它们中声明的任何内容都自动在同一包中的其他代码的范围内。因此Predef.scala
中的包对象包含导入顶级Scala范围的内容。 Scala的创造者Martin Odersky一年前在Artima上写了good introduction to them。
答案 3 :(得分:1)
单词package
是Scala中的保留关键字。但是,它是包对象的名称(标识符)。因此,如果您需要直接访问包对象,则需要使用反引号来“转义”单词包。
以下定义等同于您在问题中发布的定义:
// file package.scala in src/com
package com.test
object `package` {
val Version = 2
}
此外,Predef.scala中的行
scala.`package` // to force scala package object to be seen.
允许您像任何其他对象一样直接访问包对象。