什么是包对象,与其说是概念,不如说是它们的用法?
我试着让一个例子正常工作,我得到的唯一形式是:
package object investigations {
val PackageObjectVal = "A package object val"
}
package investigations {
object PackageObjectTest {
def main(args: Array[String]) {
println("Referencing a package object val: " + PackageObjectVal)
}
}
}到目前为止,我所做的观察是:
package object _root_ { ... }是不允许的(这是合理的),
package object x.y { ... }也是不允许的。
似乎package对象必须在直接的父包中声明,如果像上面那样编写,则需要大括号分隔的包声明表单。
它们常用吗?如果是这样的话,是怎么做的?
发布于 2010-08-04 05:48:48
通常,您会将包对象放在它所对应的包中一个名为package.scala的单独文件中。您也可以使用嵌套包语法,但这并不常见。
package对象的主要用例是,当您使用由package定义的API时,需要在package内的各个位置以及package外部的不同位置进行定义。下面是一个示例:
// file: foo/bar/package.scala
package foo
package object bar {
// package wide constants:
def BarVersionString = "1.0"
// or type aliases
type StringMap[+T] = Map[String,T]
// can be used to emulate a package wide import
// especially useful when wrapping a Java API
type DateTime = org.joda.time.DateTime
type JList[T] = java.util.List[T]
// Define implicits needed to effectively use your API:
implicit def a2b(a: A): B = // ...
}现在,该package对象中的定义在整个package foo.bar中都可用。此外,当包之外的人导入foo.bar._时,定义也会被导入。
通过这种方式,您可以防止要求API客户端发出额外的导入以有效使用库-例如,在scala-swing中,您需要编写
import swing._
import Swing._拥有所有的优点,比如onEDT和从Tuple2到Dimension的隐式转换。
发布于 2010-08-04 20:31:28
虽然Moritz的回答是正确的,但需要注意的是,包对象是对象。在其他方面,这意味着您可以使用混合继承从特征构建它们。莫里茨的例子可以写成
package object bar extends Versioning
with JodaAliases
with JavaAliases {
// package wide constants:
override val version = "1.0"
// or type aliases
type StringMap[+T] = Map[String,T]
// Define implicits needed to effectively use your API:
implicit def a2b(a: A): B = // ...
}这里的版本控制是一个抽象的特征,它表示包对象必须有一个"version“方法,而JodaAliases和JavaAliases是包含方便的类型别名的具体特征。所有这些特征都可以被许多不同的包对象重用。
发布于 2010-08-04 05:18:09
https://stackoverflow.com/questions/3400734
复制相似问题