2013-02-27 40 views

回答

132

有一些事情正在進行。

首先,Scala允許在許多方法調用中省略點和零位,所以20 seconds相當於20.seconds() *。

其次,應用「隱式轉換」。由於20IntInt沒有seconds方法,對於需要一個Int和返回的東西,確實有一個seconds方法,通過你的方法調用的範圍限制搜索的隱式轉換的編譯器搜索。

您已將DurationInt導入您的範圍。由於DurationInt是一個帶有Int參數的隱式類,因此它的構造函數定義了一個隱含的Int => DurationInt轉換。 DurationInt有一個seconds方法,所以它滿足所有的搜索條件。因此,編譯器將您的呼叫重寫爲new DurationInt(20).seconds **。

*我的意思是這個鬆散。 20.seconds()實際上是無效的,因爲seconds方法沒有參數列表,因此方法調用中省略的零件必須爲

**實際上,這並不完全正確,因爲DurationInt是一個值類,因此如果可能的話,編譯器將避免包裝整數。

+66

任何足夠先進的技術都難以區分魔術。 – ripper234 2013-02-27 05:32:12

+4

幸運的是,大多數IDE都能區分它!隱式轉換在Scala中使用得相當多。如果您只是閱讀文本文件,可能會引起混淆(「這個方法從哪裏來」),但有了適當的工具支持,您應該能夠找到解決方法,在這一點上,Scala可以非常有意義且簡潔。 (例如,如果您發現自己使用了implicits,那麼總是問問自己是否有一種方法可以使用(例如,20.seconds比'new DurationInt(20).seconds()'更具可讀性) – 2013-02-27 06:56:17

+1

在沒有他們的幫助下實現同樣的目標 http://twitter.github.com/effectivescala/#Types and Generics-Implicits – oluies 2013-02-27 08:13:51

6

在那裏發生的「魔術」被稱爲「隱式轉換」。您正在導入隱式轉換,其中一些處理Int(和Double)與Duration之間的轉換。那就是你正在處理的事情。