『壹』 Scala這個有知道的嗎,怎麼樣啊
Scala是一門多範式語言,一般常用的範式有:命令式 和 函數式,由於Scala是一門多範式語言,所以通俗來說我們可以說Scala是一門命令式編程語言同時也是函數式編程語言。
命令式:命令式是植根於馮·諾依曼體系的,一個命令式程序就是一個馮·諾依曼機的指令序列,給機器提供一條又一條的命令序列讓其原封不動的執行。通俗來說就是按照指令順序一步一步執行。
函數式:又稱泛函編程,它將計算機的計算視為數據中的函數計算。函數式編程最重要的基礎是λ(lambda)演算,λ演算對函數式編程語言有著巨大的影響。典型的函數式語言包括Erlang和Lisp等。
為什麼要用函數式:
目前來說CPU的性能發展大體上是在同等面積上集成更多的晶體管等集成電路,隨著納米技術的不斷提高,CPU能夠集成的計算單元也越來越多,但終歸是有上限的。所以在之後,單核的發展逐漸走向了多核的發展,以多核來達到性能的提升。
目前計算機的CPU基本上都是多核CPU,在使用命令式編程的時候就設涉及到多線程之間的狀態共享,需要鎖機制實現並發的控制,而鎖機制雖然保證了安全性,但是卻對性能來說是一個阻礙。
而函數式編程不會再多個線程之間共享狀態,不需要用鎖機制,可以更好的並行處理,充分利用多核CPU的並行處理能力。
如,電信行業多數使用Erlang來進行開發,就是看中了函數式編程的並行處理能力。
Scala的特點
Scala是面向對象的:Scala是一個純面向對象語言,在某種意義上來講所有數值都是對象。對象的類型和行為是由class和trait來描述的。Class的抽象可由子類化和一種靈活的基於mixin的組合機制(它可作為多重繼承的簡單替代方案)來擴展。
Scala是函數式的: Scala還是一個函數式語言,在某種意義上來講所有函數都是數值。Scala為定義匿名函數提供了一種輕量級的語法,它支持高階(higher- order)函數、允許函數嵌套、支持局部套用(currying)。Scala的case類及其內置支持的模式匹配模型代數類型在許多函數式編程語言中 都被使用。
Scala是靜態類型的:Scala配備了一套富有表現力的類型系統,該抽象概念以一種安全的和一致的方式被使用。
Scala是可擴展的:Scala的設計承認了實踐事實,領域特定應用開發通常需要領域特定語言擴展。Scala提供了一個獨特的語言組合機制,這可以更加容易地以類庫的形式增加新的語言結構:兩者結合使用可方便地定義新語句,無需擴展語法,也無需使用類似宏的元編程工具。
任何方式可以被用作中綴(infix)或後綴(postfix)操作符
閉包按照所期望的類型(目標類型)自動地被構造
Scala可與java和.NET進行互操作:Scala 設計時就考慮了與流行編程環境良好交互,如Java 2運行時環境(JRE)和 .NET框架(CLR)。特別是與主流面向對象語言,如Java和C#盡量無縫交互。Scala有像Java和C#一樣的編譯模型(獨立編譯,動態裝載 類),允許訪問成千上萬的高質量類庫。
『貳』 Scala編程語言簡介
Scala編程語言近來抓住了很多開發者的眼球 如果你粗略瀏覽Scala的網站 你會覺得Scala是一種純粹的面向對象編程語言 而又無縫地結合了命令式和函數式的編程風格 Christopher Diggins認為
不太久之前編程語言還可以毫無疑義地歸類成 命令式 或者 函數式 Scala代表了一個新的語言品種 它抹平了這些人為劃分的界限
根據David Rupp在博客中的說法 Scala可能是下下一代Java 這么高的評價讓人不禁想看看它到底是什麼東西
Scala有幾項關鍵特性表明了它的面向對象的本質 例如 Scala中的每個值都是一個對象 包括基本數據類型(即布爾值 數字等)在內 連函數也是對象 另外 類可以被子類化 而且Scala還提供了基於mixin的乎遲讓組合(mixin based position)
與只支持單繼承的語言相比 Scala具有更廣泛意義上的類重用 Scala允許定義新類的時候重用 一個類中新增的成員定義(即相較於其父類的差異之處) Scala稱之為mixin類組合
Scala還包含了若干函數式語言的關鍵概念 包括高階函數(Higher Order Function) 局部套用(Currying) 嵌套函數(Nested Function) 序列解讀(Sequence Comprehensions)等等
Scala是靜態類型的 這就允許它提供泛型類 內部類 甚至多態方法(Polymorphic Method) 另外值得一提的是 Scala被特意設計成能夠與Java和 NET互操作 Scala當前版本還不能在 NET上運行(雖然上一版可以) 但按照計劃將來可以在 NET上運行
Scala可以與Java互操作 它用scalac這個編譯器把源文件編譯成Java的class文件(即在JVM上運行的位元組碼) 你可以從Scala中調用所有的Java類庫 也同樣可以從Java應用程序中調用Scala的代碼 用David Rupp的話來說
它也可以訪問現存的數之不盡的Java類庫 這讓(潛在地)遷移到Scala更加容易
這讓Scala得以使用為Java 或者 編寫的巨量的Java類庫和框架 Scala會經常性地針對這幾個版本的Java進行測試 Scala可能也可以在更早版本的Java上運行 但沒有經過正式的測試 Scala以BSD許可發布 並且數年前就已經被認為相當穩定了
說了這么多 我們還沒有回答一個問題 為什麼我要使用Scala? Scala的設計始終貫穿著一個理念
創造一種更好地支持組件的語言 (《The Scala Programming Language》 Donna Malayeri)
也就是說軟體應該由可重用的部件構造而成 Scala旨在提供一種編程語言 能夠統一和一般化分別來自面向對象和函數式兩種不同風格的關鍵概念歲局
藉著這個目標與設計 Scala得以提供一些出眾的特性 包括
* 面旦叢向對象風格
* 函數式風格
* 更高層的並發模型
Scala把Erlang風格的基於actor的並發帶進了JVM 開發者現在可以利用Scala的actor模型在JVM上設計具伸縮性的並發應用程序 它會自動獲得多核心處理器帶來的優勢 而不必依照復雜的Java線程模型來編寫程序
* 輕量級的函數語法
o 高階
o 嵌套
o 局部套用(Currying)
o 匿名
* 與XML集成
o 可在Scala程序中直接書寫XML
o 可將XML轉換成Scala類
* 與Java無縫地互操作
Scala的風格和特性已經吸引了大量的開發者 比如Debasish Ghosh就覺得
我已經把玩了Scala好一陣子 可以說我絕對享受這個語言的創新之處
lishixin/Article/program/Java/hx/201311/26873
『叄』 編譯後生成的scala文件擴展名為
Java 源程序文件編譯後產生的文件稱為(位元組碼)文件,其擴展名為(.class)。
『肆』 scala manifest和classmanifest的區別
Manifest是scala2.8引入的一個特質,用於編譯器在運行時也能獲取泛型類型的信息。在JVM上,泛型參數類型T在運行時是被「擦拭」掉的,編譯器把T當作Object來對待,所以T的具體信息是無法得到的;為了使得在運行時得到T的信息,scala需要額外通過Manifest來存儲T的信息,並作為參數用在方法的運行時上下文。
def test[T] (x:T, m:Manifest[T]) { ... }
有了Manifest[T]這個記錄T類型信息的參數m,在運行時就可以根據m來更准確的判斷T了。但如果每個方法都這么寫,讓方法的調用者要額外傳入m參數,非常不友好,且對方法的設計是一道傷疤。好在scala中有隱式轉換、隱式參數的功能,在這個地方可以用隱式參數來減輕調用者的麻煩。
獲取class manifests的兩種基本方式:
1 def classOf[T <: Any](implicit m: scala.reflect.Manifest[T]): Class[T] = m.erasure.asInstanceOf[Class[T]
通過implicit m: scala.reflect.Manifest[T]聲明一個隱式參數,這樣scala編譯器能在編譯時提供T的類型信息了
2 def classOf[T <: Any : Manifest] : Class[T] = manifest[T].erasure.asInstanceOf[Class[T]
其中 T <: Any : Manifest,拆分成兩部分來看
T <: Any
T 是Any的子類型(即可以是任意基本類型scala.AnyVal 和引用類型 scala.AnyRef)
T : Manifest 相當於對classOf 方法currying
隱式增加參數列表如下:(implicit evidence$1: Manifest[T]),
通過manifest[T] 方法即可獲取Manifest實例
可見形式1 和形式2實質是一樣的。
應用:
1最常見的是獲取類型參數的Class,形如someMethod[Type]
如akka中源碼: def actorOf[T <: Actor : Manifest]: ActorRef = actorOf(manifest[T].erasure.asInstanceOf[Class[_ <: Actor])
class Worker extends Actor {
def receive = {
case Work(start, nrOfElements) =>
self reply Result(calculatePiFor(start, nrOfElements)) // perform the work
}
}
就可以如此使用了: val workerActorRef = actorOf[Worker]
2 編程方式創建范型數組
def evenElems[T: ClassManifest](xs: Vector[T]): Array[T] = {
val arr = new Array[T]((xs.length + 1) / 2)
for (i <- 0 until xs.length by 2)
arr(i / 2) = xs(i)
arr
}
scala> evenElems(Vector("a","b","c"))
res: Array[java.lang.String] = Array(a, c)