您好,登錄后才能下訂單哦!
Scala 是構建在 JVM 上的靜態類型的腳本語言,而腳本語言總是會有些約定來增強靈活性。關于協議在Python中是挺多的,看看Python的對象協議,有很多很多,如果對Python的對象協議了解(不了解的可以點擊此處)的比較深刻的話,其實scala的apply方法也是很好理解的,比如說 Scala 為配合 DSL 在方法調用時有這么一條約定:
在明確了方法調用的接收者的情況下,若方法只有一個參數時,調用的時候就可以省略點及括號。如 “0 to 2”,實際完整調用是 “0.to(2)”。但 “println(2)” 不能寫成 “println 10“”,因為未寫出方法調用的接收者 Console,所以可以寫成 “Console println 10”
到這里就要講到 apply 和 update 方法相關的約定,描述的是直接在對象(對象)后直接加圓括號的代碼的情況下,那就是:
用括號傳遞給變量(對象)一個或多個參數時,Scala 會把它轉換成對 apply 方法的調用;與此相似的,當對帶有括號并包括一到若干參數的進行賦值時,編譯器將使用對象的 update 方法對括號里的參數和等號右邊的對象執行調用。
我感覺這一點有點像Python里的可調用對象協議,即定義類的__call__方法,也可以得到類似的功能。
當然,兩者語言語法上肯定有差異,但是我覺得這塊兒它們的設計思想應該是異曲同工.下面通過幾個例子來理解.
1.比如數值theArray, 取數組的第一個元素的操作theArray(0)會轉換成 theArray.apply(0) 操作,這也能解釋為什么 Scala 數組取值不用中括號括下標的方式,因為它也是一次方法調用
2. anyObject("key1") 會被轉換成 anyObject.apply("key") 操作,比如 Map 的取值操作,舉個簡單的例子:
class SomeClass { def apply(key: String): String = { println("apply method called, key is: " + key) "Hello World!" } } val anyObject = new SomeClass println(anyObject("key1"))
執行后輸出結果是:
apply method called, key is: key1
Hello World!
說明是調用到了相應的 apply 方法的。
3.我們在構造 Array 或 Map 時,會簡單的寫成
val numNames = Array("zero", "one", "two")
這里也是調用的 apply 方法,我們看起來好像是作用在類 Array 上的,其實不然,而是作用在 Array 的伴生對象(object Array)上的,調用的是伴生對象 Array 的 apply 方法,即:
val numNames = Array.apply("zero", "one", "two")
同樣看個單例對象的例子,也解釋了伴生對象的 apply 方法的調用
object EMail { def apply(user: String, domain: String): String = { println("apply method called") user + "@" + domain } } val email = EMail("fantasia", "sina.com") println(email)
上面代碼執行后輸出結果是:
apply method called
fantasia@sina.com
object apply 是一種比較普遍用法。 主要用來解決復雜對象的初始化問題,同時也是單例.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。