1. 程式人生 > >Scala 包和引用

Scala 包和引用

1.包/作用域

    在Java和Scala中管理專案可以使用包結構,C和C#使用名稱空間。

    對於package,有如下幾種形式:

    形式體現:

package com.nick.impatient.people

class Person{

  val name = "Nick"

  def play(message: String): Unit ={

  }

}

    等同於:

package com.nick.impatient

package people

class Person{

  val name = "Nick"

  def play(message: String): Unit ={

  }

}

    等同於:

package com.nick.impatient{// com和com.nick的成員在這裡不可見

  package people{

    class Person{

      val name = "Nick"

      def play(message: String): Unit ={

      }

    }

  }

}

注:位於檔案頂部不帶花括號的包宣告在整個檔案範圍內有效。

        通過以上形式,發出總結:

(1)包也可以像內部類那樣巢狀,作用域原則:可以直接向上訪問。即,子package中直接訪問父package中的內容。(即:作用域

)

(2)包物件可以持有函式和變數

(3)引入語句可以引入包、類和物件

(4)原始檔的目錄和包之間並沒有強制的關聯關係

(5)可以在同一個.scala檔案中,宣告多個並列的package

(6)包名可以相對也可以絕對,比如,訪問ArrayBuffer的絕對路徑是:_root_.scala.collection.mutable.ArrayBuffer

2.包物件

    包可以包含類、物件和特質trait,但不能包含函式或變數的定義。很不幸,這是Java虛擬機器的侷限。把工具函式或常量新增到包而不是某個Utils物件,這是更加合理的做法。包物件的出現正是為了解決這個侷限。每個包都可以有一個包物件。你需要在父包中定義它,且名稱與子包一樣。

package com.nick.impatient

package object people {

  val defaultName = "Nick"

}

package people {

  class Person {

    var name = defaultName // 從包物件拿到的常置

  }

}

3.包可見性

    在Java中,沒有被宣告為public、private或protected的類成員在包含該類的包中可見。在Scala中,你可以通過修飾符達到同樣的效果。以下方法在它自己的包中可見:

package com.nick.impatient.people

class Person {

  private[people] def description="人的名字:" + name

}

    當然,也可以將可見度延展到上層包:

private[impatient] def description="人的名字:" + name

4.引入

    在Scala中,import語句可以出現在任何地方,並不僅限於檔案頂部。import語句的效果一直延伸到包含該語句的塊末尾:這是個很有用的特性,尤其是對於通配引入而言。從多個源引入大量名稱總是讓人擔心。事實上,有些Java程式設計師特別不喜歡通配引入,以至於從不使用這個特性,而是讓IDE幫他們生成一長串引入語句。通過將引入放置在需要這些引入的地方,你可以大幅減少可能的名稱衝突。

5.重新命名和隱藏方法

(1) 重新命名:

    如果你想要引人包中的幾個成員,可以像這樣使用選取器( selector),而且選取的同時,可以重新命名:

import java.util.{ HashMap=>JavaHashMap, List}

import scala.collection.mutable._

    這樣一來,JavaHashMap就是java.utiI.HashMap,而HashMap則對應scala.collection.mutable.HashMap。

(2)隱藏:

    選取器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._

    和Java程式一樣,java.lang總是被引入。接下來,scala包也被引入,不過方式有些特殊。不像所有其他引入,這個引入被允許可以覆蓋之前的引入。舉例來說,scala.StringBuilder覆蓋java.lang.StringBuilder而不是與之衝突。最後,Predef物件被引入。它包含了相當多有用的函式,這些同樣可以被放置在scala包物件中,不過Predef在Scala還沒有加入包物件之前就存在了。

    由於scala包預設被引入,對於那些以scala開頭的包,你完全不需要寫全這個字首。例如:

    collection.mutable.HashMap

    上述程式碼和以下寫法一樣好:

    scala.collection.mutable. HashMap