什么是包装对象,而不是概念,而是它们的用法?
我试图让一个例子正常工作,我开始工作的唯一形式如下:
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 { ... }
也是不允许的。
似乎必须在直接父包中声明包对象,如果如上所述,则需要以大括号分隔的包声明表单。
它们是否常用?如果是这样,怎么样?
答案 0 :(得分:124)
通常,您会将包对象放在与其对应的包中名为package.scala
的单独文件中。您也可以使用嵌套包语法,但这很不寻常。
包对象的主要用例是,当您使用包定义的API时,需要在包内的各个位置以及包外部进行定义。这是一个例子:
// 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 = // ...
}
现在,整个包foo.bar
中可以使用该包对象中的定义。此外,当该包之外的人导入foo.bar._
时,将导入定义。
通过这种方式,您可以阻止要求API客户端发布其他导入以有效地使用您的库 - 例如在scala-swing你需要写
import swing._
import Swing._
拥有onEDT
之类的善意以及Tuple2
至Dimension
的隐式转化。
答案 1 :(得分:56)
虽然莫里茨的答案很明显,但需要注意的另一件事是包装对象是对象。除此之外,这意味着您可以使用混合继承从特征构建它们。莫里茨的例子可以写成
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 = // ...
}
此处Versioning是一个抽象特征,它表示包对象必须具有“version”方法,而JodaAliases和JavaAliases是包含方便类型别名的具体特征。所有这些特征都可以被许多不同的包对象重用。
答案 2 :(得分:7)
你可能做得更糟,而不是直接去源头。 :)
https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/library/scala/package.scala
答案 3 :(得分:2)
包对象的主要用例是,当您使用包定义的API时,需要在包内以及包外的各个位置进行定义。
Scala 3 并非如此,原定于2020年中发布的based on Dotty的发布版本为in here:
顶级定义
各种定义都可以写在顶层。
不再需要打包对象,将逐步淘汰。
package p
type Labelled[T] = (String, T)
val a: Labelled[Int] = ("count", 1)
def b = a._2
def hello(name: String) = println(i"hello, $name)