摘自《快学Scala》
Scala的包和Java的包或者C++的命名空间的目的是相同的:管理大型程序中的名称。
如:
Map这个名称可以同时出现在scala.collection.immutable和scala.collection.mutable包而不会冲突。要访问它们中的任何一个,可以使用完全限定的名称scala.collection.immutable.Map或scala.collection.mutable.Map,也可以使用引入语句提供一个更短小的别名。
要增加条目到包中,可以将其包含在包语句当中,如:
package com{
package horstmann{
package impatient{
class Employee
...
}
}
}
这样,类名Employee就可以在任意位置以com.horstmann.impatient.Employee访问到了。
与对象或类的定义不同,同一个包可以定义在多个文件当中。上面这段代码可能出现在Employ.scala中,另一个名为Manager.scala的文件可能会包含:
package com{
package horstmann{
package impatient{
class Manager
...
}
}
}
**不需要将Employee.scala和Manager.scala放在com/hortmann/impatient目录中。
在Scala中,包的作用域比起Java更加前后一致。Scala的包和其他作用域一样支持嵌套,你可以访问上层作用域中的名称。如:
package com{
package horstmann{
package Utils{
def percentOf(value:Double,rate:Double)=value * rate /100
...
}
package impatient{
class Employee{
def giveRaise(rate:scala.Double){
salary += Utils.percentOf(salary, rate)
}
}
}
}
}
绝对包名:
val subordinates = _root_.scala.collection.mutable.ArrayBuffer[Employee]
package com.horstmann.impatient{
//com和com.horstmann的成员在这里不可见
package people{
clas Person
...
}
}
这样的包语句限制了可见的成员,现在com.horstmann.collection包不再能够以collection访问到了。
除了用嵌套标记法以外,也可以在文件顶部使用package语句,不带花括号。例如:
package com.horstmann.impatient
package people
class Person
...
这等同于
package com.horstmann.impatient{
package people{
class Person
...
//直到文件末尾
}
}
如果文件中的所有代码属于同一个包的话(这也是通常的情形),这是更好的做法。
在上面的示例中,文件的所有内容都属于com.horstmann.impatient.people,但com.horstmann.impatient包的内容是可见的,可以被直接饮用。
包可以包含类,对象和特质,但不能包含函数或变量的定义。
每个包都可以有一个包对象,你需要在父包中定义它,且名称与子包一样,例如:
package com.hordstmann.impatient
package object people{
val defaultName = "John Q.Public"
}
package people{
class Person{
var name = defaultName //从包对象拿到的常量
}
...
}
//defaultName不需要加限定词,因为它位于同一个包内,在其他地方,这个常量可以用com.horstmann.impatient,.people.defaultName访问。
以下方法在它自己的包中可见:
package com.horstmann.impatient.people
class Person{
private[people] def description = "A person with name " + name
...
}
//可以将可见度延展到上层包
private[impatient] def description = "A person with name " + name
引入语句让你可以使用更短的名称而不是原来较长的名称:
import java.awt.Color
这样,就可以在代码中写Color而不是java.awt.Color了。
//引入某个包的全部成员:
import java.awt._
//引入类或对象的所有成员:
import java.awt.Color._
val c1 =RED //Color.RED
val c2 =- decode("#ff0000") //Color.decode
在Scala中,import语句可以出现在任何地方,并不仅限于文件顶部。import的效果一直延伸到包含该语句的块末尾。
class Manager{
import scala.collection.mutable._
val subordinates = new ArrayBuffer[Employee]
}
通过将引用放置在需要这些引入的地方,可以大幅减少可能的名称冲突。
//选取器 {}
import java.awt.{Color, Font}
//选取器语法还允许重命名选到的成员
import java.util.{HashMap => JavaHashMap}
import scala.collection.mutable._
//这样,JavaHashMap就是java.util.HashMap,而HashMap则对应scala.collection.mutable.HashMap
//选取器HashMap=>_将隐藏某个成员名而不是重命名它,这仅在你需要引入其他成员时有用:
import java.util.{HashMap => _,_}
import scala.collection.mutable._
//现在,HashMap无二义的指向scala.collection.mutable.HashMap,因为java.util.HashMap被隐藏起来了。
每个Scala程序都隐式的以如下代码开始:
import java.lang._
import scala._
import Predef._