Scala 包和引入

摘自《快学Scala》

0.重点

  • 包可以像内部类那样嵌套
  • 包路径不是绝对路径
  • 包声明链x.y.z并不自动将中间包x和x.y变成可见
  • 位于文件顶部不带花括号的包声明在整个文件范围内有效
  • 包对象可以持有函数和变量
  • 引入语句可以引入包,类和对象
  • 引入语句可以出现在任何位置
  • 引入语句可以重命名和隐藏特定成员
  • java.lang, scala和Predef 总是被引入

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目录中。

2.作用域规则

在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]

3.串联式包语句

package com.horstmann.impatient{
    //com和com.horstmann的成员在这里不可见
    package people{
        clas Person
        ...
    }
}

这样的包语句限制了可见的成员,现在com.horstmann.collection包不再能够以collection访问到了。

4.文件顶部标记法

除了用嵌套标记法以外,也可以在文件顶部使用package语句,不带花括号。例如:

package com.horstmann.impatient
package people

class Person
...

这等同于

package com.horstmann.impatient{
    package people{

        class Person
        ...
        //直到文件末尾
    }
}

如果文件中的所有代码属于同一个包的话(这也是通常的情形),这是更好的做法。
在上面的示例中,文件的所有内容都属于com.horstmann.impatient.people,但com.horstmann.impatient包的内容是可见的,可以被直接饮用。

5.包对象

包可以包含类,对象和特质,但不能包含函数或变量的定义。
每个包都可以有一个包对象,你需要在父包中定义它,且名称与子包一样,例如:

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访问。

6.包可见性

以下方法在它自己的包中可见:

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

7.引入

引入语句让你可以使用更短的名称而不是原来较长的名称:

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

8.任何地方都可以声明引入

在Scala中,import语句可以出现在任何地方,并不仅限于文件顶部。import的效果一直延伸到包含该语句的块末尾。

class Manager{
    import scala.collection.mutable._
    val subordinates = new ArrayBuffer[Employee]
}

通过将引用放置在需要这些引入的地方,可以大幅减少可能的名称冲突。

9.重命名和隐藏方法

//选取器 {}
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被隐藏起来了。

10.隐式引入

每个Scala程序都隐式的以如下代码开始:

import java.lang._
import scala._
import Predef._
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值