一、前言
前面介紹了Scala的Object,由於中間論文的時間耽誤了些時間,接着繼續學習Scala的Packaging和Imports
二、Packaging and Imports
Scala的包用法與Java類似,但更靈活。在class文件頂端使用package語法,並且可以使用帶中括號的package語法,與Java相比,Scala的導入有如下特點
· 可在任何地方使用import聲明
· 可導入類、包、對象
· 對導入的成員隱藏或者重命名
並且在Scala中,隱式導入了java.lang._和scala.lang._兩個包,_與Java中的*一樣,表示導入包下所有的類,除了上述兩個包,scala.Predef對象也被隱式導入,可以詳細閱讀Predef的源代碼,里面包含了很多Scala的語法
2.1 帶有中括號符號的包
1. 問題描述
你想使用一個嵌套風格的包符號,類似於C++和C#命名空間的符號
2. 解決方案
將類放置在有中括號的包名中,如下所示
package com.hust.grid { class Foo { override def toString = "I am com.hust.grid.Foo" } }
類的規范名字是com.hust.grid.Foo,其等效於如下代碼
package com.hust.grid class Foo { override def toString = "I am com.hust.grid.Foo" }
使用這種方法,可以在一個文件中放置多個package,也可以使用“中括號”風格嵌套包
下面示例展示了三個不同的Foo類,Foo類在不同的包中
// a package containing a class named Foo package orderentry { class Foo { override def toString = "I am orderentry.Foo" } } // one package nested inside the other package customers { class Foo { override def toString = "I am customers.Foo" } package database { // this Foo is different than customers.Foo or orderentry.Foo class Foo { override def toString = "I am customers.database.Foo" } } } // a simple object to test the packages and classes object PackageTests extends App { println(new orderentry.Foo) println(new customers.Foo) println(new customers.database.Foo) }
輸出結果如下
I am orderentry.Foo
I am customers.Foo
I am customers.database.Foo
3. 討論
可以使用在文件頂端聲明包名,但是也可以使用帶中括號風格的包名來將多個類和包放置在同一個文件下
2.2 導入一個或多個成員
1. 討論
你想要將一個或多個成員導入到當前程序的作用域中
2. 解決方案
下面是導入一個類的語法
import java.io.File
你可以導入多個類
import java.io.File import java.io.IOException import java.io.FileNotFoundException
或者使用Scala的導入方式
import java.io.{File, IOException, FileNotFoundException}
或者導入java.io包下所有的類
import java.io._
_與Java中的通配符*含義相同
3. 討論
Scala的導入比Java更的使用為靈活,在Scala中,你可以在任何地方放置導入申明,如Scala文件中可包含多個類或者包,此時,可以在不同的包中聲明導入,使得具有不同的作用域
package foo import java.io.File import java.io.PrintWriter class Foo { import javax.swing.JFrame // only visible in this class // ... } class Bar { import scala.util.Random // only visible in this class // ... }
你甚至可以在方法中、函數中、代碼塊中放置導入申明
class Bar { def doBar = { import scala.util.Random println("") } }
2.3 對導入成員重命名
1. 問題描述
在導入成員時重命名成員以避免命名空間沖突或混淆
2. 解決方案
使用下面語法將成員進行重命名
import java.util.{ArrayList => JavaList}
在代碼中,可以使用如下方式使用
val list = new JavaList[String]
也可以一次性重命名多個類
import java.util.{Date => JDate, HashMap => JHashMap}
當進行重命名后,之前的名字不能正常使用
// error: this won't compile because HashMap was renamed // during the import process val map = new HashMap[String, String]
3. 討論
重命名成員可以命名空間沖突或混淆
import java.util.{HashMap => JavaHashMap} import scala.collection.mutable.{Map => ScalaMutableMap}
你不僅可以重命名類,也可以重命名類的成員,如方法
2.4 在導入時隱藏類
1. 問題描述
當從同一包導入其他成員時,你想要隱藏一個或多個類
2. 解決方案
其類似於重命名,但是使用_符號代替重命名的名字,如下面示例隱藏了Random類,但是導入了java.util中的所有其他類
import java.util.{Random => _, _}
其中,第一個_符號代表隱藏Random類,第二個_符號代碼導入所有的其他類,並且導入通配符必須要放在最后,否則發生錯誤
若需要隱藏多個成員,可以使用如下做法
import java.util.{List => _, Map => _, Set => _, _}
2.5 使用靜態導入
1. 問題描述
你想要像Java靜態導入那樣導入成員,以便可以直接使用成員名字,而不需要加類名的前綴
2. 解決方案
使用下面方法導入java.Math中所有的成員
import java.lang.Math._
此時,你就可以不需要加前綴來使用Math類中的成員
2.6 在任何地方使用Import申明
1. 問題描述
你想要在任何地方使用import申明,以便控制作用域和管理代碼
2. 解決方案
你可以在類定義之前使用導入,然后在類中使用
package foo import scala.util.Random class ImportTests { def printRandom { val r = new Random } }
也可以在類中導入
package foo class ImportTests { import scala.util.Random def printRandom { val r = new Random } }
這使得import的作用域在類中,也可以將import的作用域限制在方法中
def getRandomWaitTimeInMinutes: Int = { import com.alvinalexander.pandorasbox._ val p = new Pandora p.release }
還可以將import作用域控制在代碼塊中
def printRandom { { import scala.util.Random val r1 = new Random // this is fine } val r2 = new Random // error: not found: type Random }
3. 討論
import是按照順序讀取的,放置import的位置也決定了其作用域
// this doesn't work because the import is after the attempted reference class ImportTests { def printRandom { val r = new Random // fails } } import scala.util.Random
當文件中包含多個類和包時,你可以結合import申明和包引入方法來限制import語句的作用域
package orderentry { import foo._ // more code here ... } package customers { import bar._ // more code here ... package database { import baz._ // more code here ... } }
三、總結
本篇博文講解了Scala中的包和導入方面的知識點,最主要的就是作用域問題,知識點也相對簡單,也謝謝各位園友的觀看~