le point de s implicites Le tuff est de remplir des trucs ennuyeux quand il n'y a clairement qu'une seule bonne façon de le faire.
Dans le cas de les paramètres implicites le compilateur insère un paramètre du contexte qui doit être ce à quoi vous pensiez. Par exemple,
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
Depuis que nous avons marqué le taux d'imposition en tant que paramètre implicite, et fourni une variable implicite qui peut être rempli en cas de besoin, on n'a pas besoin de préciser le taux d'imposition. Le compilateur remplit automatiquement withTax(15.00)(sales_tax)
Dans le cas des conversions implicites , le compilateur recherche une méthode qui peut prendre un type qu'il a et le convertir au type qui est nécessaire. Cette conversion ne peut pas être chaînée dans des circonstances normales, vous devez donc obtenir ce dont vous avez besoin en une étape.
Il y a deux cas où des conversions implicites sont susceptibles d'entrer en jeu. L'un est dans le paramètre d'un appel de méthode - si le type est faux, mais il peut être converti au bon type (d'une manière exacte), alors le compilateur va convertir pour vous. L'autre est dans la présence d'un appel de méthode - si le type réellement utilisé n'a pas la méthode disponible, mais vous pouvez le convertir en un type qui a cette méthode, puis la conversion aura lieu, puis la méthode sera appelée.
Regardons un exemple de chacun.
implicit def float2taxrate(f: Float) = TaxRate(BigDecimal(f))
scala> withTax(15.00)(0.15f)
res1: scala.math.BigDecimal = 17.250000089406967200
Ici, nous appelons un taux d'imposition explicite de 0.15f
. Cela ne correspond pas au paramètre, qui doit être de type TaxRate
, mais le compilateur voit que nous pouvons transformer les flottants en taux d'imposition en utilisant le float2taxrate
implicite. Donc, il le fait pour nous, en appelant withTax(15.00)(float2taxrate(0.15f))
Maintenant l'autre exemple.
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 ne dispose pas d'une méthode rounded
, donc withTax(15.00)(0.15f)
ne devrait pas être en mesure d'appeler un (car il renvoie un BigDecimal
). Mais nous avons défini un Currency
qui a une méthode rounded
, et une conversion en Currency
, donc la conversion implicite remplit tous les détails: bigdec2currency(withTax(15.00)(0.15f)).rounded
.
Dans le cas de la conversion de Int
à BigInt
, le compilateur l'utilisera quand, par exemple, il essayera d'ajouter 7 + BigInt(5)
. Cela ne va pas fonctionner normalement - 7
est un Int
et Int
ne sait pas comment ajouter lui-même à BigInt
. Mais BigInt
a une méthode +
qui peut s'ajouter à un autre BigInt
. Et le compilateur voit que si seulement il pouvait convertir 7
en BigInt
, il pourrait utiliser cette méthode. La conversion implicite permet cette conversion, donc elle traduit 7 + BigInt(5)
en int2bigInt(7)+BigInt(5)
.
(Note: int2bigInt
est définie à l'intérieur BigInt
, afin de l'utiliser, vous devez import BigInt._
Et à son tour remet à la méthode apply(i: Int)
de l'objet BigInt
, qui est ce que vous permet d'écrire BigInt(5)
et le faire fonctionner (plutôt que. avoir à passer une chaîne comme avec BigInteger
en Java).)
Je pense que vous faites référence à des conversions implicites. Les paramètres implicites sont une chose légèrement différente. – GClaramunt
[Programmation dans Scala 1ère édition] (http://www.artima.com/pins1ed/): [Conversions implicites et paramètres] (http://www.artima.com/pins1ed/implicit-conversions-and-parameters). html) – user272735