Scala开发教程(53): 引用包中的代码

jerry Scala 2015年11月25日 收藏

当我们把代码以层次关系放到包中时,它不仅仅可以帮助人们浏览代码,同时也说明了同一包中的代码具有某些相关性。Scala可以利用这些相关性来简化代码引用,比较使用短名称,而无需使用包的全路径来访问类定义。
下面我们给出三个简单的例子:

  1. package bobsrockets{
  2. package navigation{
  3. class Navigator{
  4. var map =new StarMap
  5. }
  6. class StarMap
  7. }
  8. class Ship {
  9. val nav= new navigation.Navigator
  10. }
  11. class fleets{
  12. class Fleet{
  13. def addShip() {new Ship}
  14. }
  15. }
  16. }

在第一个例子中,正如你可以预见的一样,访问同一包中定义的类型,无需使用前缀,直接使用类型的名称即可访问,也就是可以直接使用 new StarMap。类StarMap 和Navigator定义在同一个包中。
第二个例子,嵌套的package 也可以在其父包中被同级别的其它类型直接访问,而无需使用全称,因此第二个例子可以使用navigation来直接访问navigation包,而无需添加bobsrockets.
第三个例子,但使用包定义的{}语法结构时,内层的类型可以直接访问其外层定义的类型,因此在类Fleet中可以直接访问外层定义的类型Ship。

要注意的是这种用法只适用于你明确嵌套包定义,如果你采用Java语言风格-一个文件定义一个包,那么你只能访问该包中定义的类型。

访问包定义的类型还有一个技巧值得说明一下,比如你定义了一些类型之间可能存在相互隐藏的关系,也就是内层定义的同名类型可能会隐藏外层定义的同名类型,那么你怎么来访问外层定义的类型呢?请看下例:

  1. package launch{
  2. class Booster3
  3. }
  4.  
  5. package bobsrockets{
  6. package navigtion{
  7. package launch{
  8. class Booster1
  9.  
  10. }
  11.  
  12. class MissionControl{
  13. val booster1 =new launch.Booster1
  14. val booster2=new bobsrockets.launch.Booster2
  15. val booster3=new _root_.launch.Booster3
  16.  
  17. }
  18. }
  19.  
  20.  
  21. package launch{
  22. class Booster2
  23. }
  24. }

如何来访问Booster1,Booster2,和Booster3呢? 访问Booster1 比较容易,Booster2可以通过全称来访问。那么如何访问最外层的Booster3呢?内层的包launch隐藏了这个外部的同名包。为解决这种情况,Scala提供了_root_,也就是所有最外层的类型都可以当成定义在_root_包中。因此_root_.launch.Booster3可以访问最外层定义的类型。