在2.8版本之前,能放入package内的只有class、trait和object,这些对象位于package 的最顶层是目前最常见的定义。但是2.8之后,定义的所有类型也可以放到class中。如果你有一些辅助方法、变量、常量想在整个包的范围内可控,可以将其放到包的最顶层,即放到package object中。每一个package可以有一个package object,所有在package object中定义的类型都可以看作是package自身的成员。
例如,假定类Fruit和三个Fruit对象在gardening.fruits包中:
1 2 3 4 5 6 |
// in file gardening/fruits/Fruit.scala package gardening.fruits case class Fruit(name: String, color: String) object apple extends Fruit("Apple", "green") object plum extends Fruit("Plum", "blue") object banana extends Fruit("Banana", "yellow") |
假定你将一个常量planted和方法showFruit直接加入到gardening包中,使用下面的方法可以做到:
1 2 3 4 5 6 7 8 |
// in file gardening/fruits/package.scala package gardening package object fruits { val planted = List(apple, plum, banana) def showFruit(fruit: Fruit) { println(fruit.name +"s are "+ fruit.color) } } |
从语法上来看,package object看起来像是普通object的定义,唯一的却别是包含了package关键字。这是一个package object,而不是普通的object。花括号之间的内容可以包含你想要定义的。在上面的例子中,package object包含了planted变量和showFruit方法。
通过这个定义,在同一包内的其他代码都可以使用package object的定义 。例如,下面的object PrintPlanted 导入了通配符_,不仅导入了class和object,还导入了planted常量和showFruit方法。
1 2 3 4 5 6 7 8 9 |
// in file PrintPlanted.scala import gardening.fruits._ object PrintPlanted { def main(args: Array[String]) { for (fruit: Fruit <- fruits.planted) { showFruit(fruit) } } } |
除了变量和方法外,package object还可以包含隐式转换和类型别名等内容,package object还可以继承class和trait。
例如:
1 2 3 4 5 |
package object debugo{ type HashMap[A,B] = scala.collection.mutable.HashMap[A,B]; val HashMap = scala.collection.mutable.HashMap def print = println("hello, debugo") } |
这样,package object就像使用类的伴生对象一样被使用:
1 2 3 4 5 |
object Test extends Application{ val myMap: com.debugo.HashMap[String,String]= null; println(com.debugo.HashMap) com.debugo.print } |
参考
http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html
是啊,要是乌克娜娜回来就不需要陶喜儿的冰魔法了。
其实离开了的东西又怎么能算是我的呢。离开了的朋友又怎么能叫做朋友呢。虽然我还是爱她们。