隱含的點當只有一個正確的方法去做時,凝灰岩將填補無聊的樣板材料。
對於隱式參數的情況,編譯器從上下文插入一個參數,該參數必須是您所想的。例如,
case class TaxRate(rate: BigDecimal) { }
implicit var sales_tax = TaxRate(0.075)
def withTax(price: BigDecimal)(implicit tax: TaxRate) = price*(tax.rate+1)
scala> withTax(15.00)
res0: scala.math.BigDecimal = 16.1250
由於我們已經標出稅率作爲一個隱含參數,並提供了可以在需要時填寫的隱含變量,我們並不需要指定稅率。編譯器在withTax(15.00)(sales_tax)
自動填充的隱式轉換的情況下,編譯器會尋找能接受它有一個類型,並將其轉換爲所需要的類型的方法。此轉換在正常情況下無法鏈接,因此您必須在一步步驟中獲得所需的內容。
有兩種情況可能會發生隱式轉換。一個是在參數的一個方法調用 - 如果類型是錯誤的,但它可以轉換爲正確的類型(正好以一種方式),那麼編譯器會爲你轉換。另一種是在存在的方法調用 - 如果實際使用的類型沒有可用的方法,但可以將其轉換爲具有該方法的類型,那麼轉換將發生,然後方法將被調用。
讓我們看看每個例子。
implicit def float2taxrate(f: Float) = TaxRate(BigDecimal(f))
scala> withTax(15.00)(0.15f)
res1: scala.math.BigDecimal = 17.250000089406967200
在這裏,我們稱明確的稅率爲0.15f
。這與參數不匹配,該參數必須是TaxRate
,但編譯器發現我們可以使用隱含的float2taxrate
將花車變成稅率。所以它對我們來說,呼叫withTax(15.00)(float2taxrate(0.15f))
現在的另一個例子。
class Currency(bd: BigDecimal) {
def rounded = bd.setScale(2,BigDecimal.RoundingMode.HALF_EVEN)
}
implicit def bigdec2currency(bd: BigDecimal) = new Currency(bd)
scala> withTax(15.00)(0.15f).rounded
res66: scala.math.BigDecimal = 17.25
的BigDecimal沒有rounded
方法,所以withTax(15.00)(0.15f)
不應該是能夠調用一個(因爲它返回一個BigDecimal
)。但是我們定義了一個Currency
,它有一個rounded
方法,並且轉換爲Currency
,因此隱式轉換會填充所有詳細信息:bigdec2currency(withTax(15.00)(0.15f)).rounded
。
在從Int
到BigInt
的轉換的情況下,編譯器將在例如嘗試添加7 + BigInt(5)
時使用它。這不會正常工作 - 7
是一個Int
和Int
不知道如何將自己添加到BigInt
。但BigInt
有一個方法+
可以將自己添加到另一個BigInt
。編譯器看到,如果只有它可以將7
轉換爲BigInt
,它可以使用該方法。隱式轉換允許進行轉換,因此它將7 + BigInt(5)
轉換爲int2bigInt(7)+BigInt(5)
。
(注:int2bigInt
在裏面BigInt
定義,所以使用它,你必須import BigInt._
它反過來又推遲到BigInt
對象的apply(i: Int)
方法,這是什麼讓你寫BigInt(5)
和它的工作(而不是。必須通過與Java中的BigInteger
一樣的字符串)。)
我認爲您指的是隱式轉換。隱式參數稍有不同。 – GClaramunt 2010-05-18 22:53:12
[Scala編程第1版](http://www.artima.com/pins1ed/):[隱式轉換和參數](http://www.artima.com/pins1ed/implicit-conversions-and-parameters。 html) – user272735 2012-06-29 09:20:18