暗黙的なもののポイントは、それを行う正しい方法が明らかに 1 つしかない場合に、退屈な定型文を埋めることです。
暗黙的なパラメーターの場合、コンパイラーは、あなたが考えていたものでなければならないコンテキストからパラメーターを挿入します。例えば、
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)
暗黙的な変換の場合、コンパイラは、それが持つ型を取り、それを必要な型に変換できるメソッドを探します。この変換は通常の状況では連鎖できないため、必要なものを1 つのステップで取得する必要があります。
暗黙の変換が行われる可能性が高いケースが 2 つあります。1 つはメソッド呼び出しのパラメーターにあります。型が間違っていても、正しい型に (正確に 1 つの方法で) 変換できる場合は、コンパイラーが変換します。もう 1 つは、メソッド呼び出しが存在する場合です。実際に使用されている型に使用可能なメソッドがなくても、そのメソッドを持つ型に変換できる場合、変換が行われ、メソッドが実行されます。呼ばれます。
それぞれの例を見てみましょう。
implicit def float2taxrate(f: Float) = TaxRate(BigDecimal(f))
scala> withTax(15.00)(0.15f)
res1: scala.math.BigDecimal = 17.250000089406967200
ここでは、明示的な税率を と呼びます0.15f。これは type でなければならないパラメータと一致しませんTaxRateが、コンパイラは暗黙的な を使用して float を税率に変換できることを認識しています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持つ aと への変換を定義したので、暗黙的な変換によってすべての詳細が埋められます: 。roundedCurrencybigdec2currency(withTax(15.00)(0.15f)).rounded
Intからへの変換の場合BigInt、コンパイラは、たとえば を追加しようとするときにそれを使用し7 + BigInt(5)ます。これは正常に機能しません。7は であり、IntにInt自身を追加する方法を知りませんBigInt。しかし、別の に自分自身を追加できるBigIntメソッドがあります。そして、コンパイラは、 に変換できれば、そのメソッドを使用できることを認識します。暗黙的な変換ではその変換が許可されるため、 に変換されます。+BigInt7BigInt7 + BigInt(5)int2bigInt(7)+BigInt(5)
(注:int2bigIntは 内で定義されているBigIntため、使用するには を使用する必要がありますimport BigInt._。また、オブジェクトのapply(i: Int)メソッドに従います。これにより、( Javaのように文字列を渡す必要はなく) 記述して機能させることができます)。 .)BigIntBigInt(5)BigInteger