什么是包对象,而不是概念,但它们的用途?
我试图找一个工作的例子,我开始工作的唯一形式如下:
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我到目前为止所做的观察是:
package object _root_ { ... }
Run Code Online (Sandbox Code Playgroud)
是不允许的(这是合理的),
package object x.y { ... }
Run Code Online (Sandbox Code Playgroud)
也是不允许的.
似乎必须在直接父包中声明包对象,如果如上所述,则需要包含大括号的包声明表单.
它们是常用的吗?如果是这样,怎么样?
Mor*_*itz 125
通常,您会将包对象放在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 = // ...
}
Run Code Online (Sandbox Code Playgroud)
现在,包内对象中的定义在整个包中可用foo.bar
.此外,当该包外部的人导入时,将导入定义foo.bar._
.
通过这种方式,您可以阻止要求API客户端发出额外的导入以有效地使用您的库 - 例如,在Scala-swing中您需要编写
import swing._
import Swing._
Run Code Online (Sandbox Code Playgroud)
让所有喜欢善良onEDT
和隐式转换Tuple2
到Dimension
.
Dav*_*ith 56
虽然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 = // ...
}
Run Code Online (Sandbox Code Playgroud)
这里Versioning是一个抽象特征,它表示包对象必须有一个"version"方法,而JodaAliases和JavaAliases是包含方便类型别名的具体特征.所有这些特征都可以被许多不同的包对象重用.
包对象的主要用例是,当您使用包定义的 API 时,您需要在包内以及包外的各个位置进行定义。
Scala 3并非如此,它计划于 2020 年年中发布,基于Dotty,因为在这里:
顶级定义
各种定义都可以写在顶层。
不再需要包对象,将被逐步淘汰。
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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
30908 次 |
最近记录: |