2017-03-26 64 views
3

對象包語法相比簡單地讓函數和變量添加到包中有什麼優勢?Scala包對象背後的動機

例如:

package object something { 
    def hello = 0 
} 

package something { 

} 

爲什麼不乾脆:

package something { 
    def hello = 0 
    // other classes and such 
} 
+0

不確定你的意思是「簡單地讓你添加函數和變量到一個包」。包對象旨在提供包中的常量。 –

+0

增加了一個例子。 – Derlin

回答

6

你甚至可以更進一步:爲什麼有包可言,當我們有object S'

Scala旨在用作「託管語言」,即可以很好地託管在另一種語言的平臺之上的語言。 Scala的原始實現是在Java平臺和ISO通用語言基礎架構平臺上(或者說它的主要實現,.NET和Mono)。今天,我們也在ECMAScript平臺(Scala.js)上實現了一個實現,例如,Java平臺實現也可以在Android上使用。你也可以想象其他有趣的平臺,你想運行Scala,例如在Windows UWP平臺,斯威夫特/的Objective-C /核心基金/ MacOS的/的iOS/tvOS/watchOS平臺,侏儒/ GObject的平臺,Qt的/ C++平臺等

Scala沒有只是打算在這些平臺上運行,它打算滿足兩個,往往相互衝突,目標:

  • 高性能
  • 與「本土」的緊密集成,感覺

小號o,在斯卡拉,執行問題是語言設計的一部分。 (Clojure的設計師Rich Hickey曾在一次演講中表示「JVM是而不是的實現細節」,這同樣適用於Scala)。一個很好的例子是正確的尾部調用:爲了支持正確的尾部調用,Scala必須管理自己的堆棧,而不是在JVM等平臺上使用主機平臺的本地調用堆棧,但這意味着您不能再輕鬆地從平臺上的其他代碼調用Scala代碼,反之亦然。所以,雖然適當的尾部調用會很好,但Scala會處理不太強大的適當的立即尾部遞歸。

理論上,Scala中只需要object S,trait S,方法,type s和路徑(.#)。其他一切基本上都是爲了簡化與主機平臺的集成。這包括,例如,null,class es和package s。

理想情況下,應該有一個從宿主平臺構造到Scala構造的簡單映射,反之亦然。因此,例如,Scala方法和JVM方法之間有一個簡單的映射。 JVM接口和Scala特性之間的簡單映射只有抽象成員。有Scala特性和JVM類之間的簡單映射,這就是爲什麼Scala也有類(冗餘)概念的原因。同樣,在Scala object和JVM package(或CLI namespace s)之間也沒有簡單的映射,這就是爲什麼Scala也有(冗餘)概念package的原因。

然而,我們真的package S(其中,畢竟,有些像斯卡拉object S)擁有成員。但JVM package和CLI namespace s不能有除interface s和class es之外的成員,並且由於我們僅在Scala中介紹它們以與主機平臺兼容,因此它們與主機平臺不兼容是沒有意義的通過添加成員給他們。

因此,我們引入了另一個單獨的概念,package object,它擁有我們想要添加到package的成員,但不能,因爲主機平臺的互操作性。

TL;博士

  • 我們,因爲互操作的package S(儘管我們已經有了object s,它可以做同樣的事情package S)
  • 我們想package s有會員
  • package s不能有會員,因爲interop
  • 所以,我們有package object s作爲同伴package s
+0

感謝您的回答。所以原因只在於實施限制。我想知道這是否也是爲了避免將包方法/字段分散到多個文件中。 – Derlin

+0

@Derlin理論上你可以從不同的文件中獲取所有頂級的defs,vals,types,...並將它們編譯成一個包對象。但我認爲這會導致增量和單獨編譯的問題。 –