el punto de s implícitos Tuff es rellenar cosas aburridas cuando claramente hay una sola forma correcta de hacerlo.
En el caso de los parámetros implícitos el compilador inserta un parámetro del contexto que debe ser lo que estaba pensando. Por ejemplo,
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
Como nos hemos marcado la tasa de impuestos como un parámetro implícito, y proporciona una variable implícita que puede ser llenado en cuando es necesario, no es necesario especificar el tipo de gravamen. El compilador rellena automáticamente withTax(15.00)(sales_tax)
En el caso de las conversiones implícitas , el compilador busca un método que puede tener un tipo que tiene y lo convierten en el tipo que se necesita. Esta conversión no puede encadenarse en circunstancias normales, por lo que debe obtener lo que necesita en un paso.
Existen dos casos en los que es probable que entren en juego conversiones implícitas. Uno está en el parámetro de una llamada a método: si el tipo es incorrecto, pero se puede convertir al tipo correcto (exactamente de una manera), el compilador convertirá para usted. El otro se encuentra en el presencia de una llamada a método - si el tipo realmente utilizado no tiene el método disponible, pero puede convertirlo a un tipo que sí lo tenga, se realizará la conversión y luego método será llamado.
Veamos un ejemplo de cada uno.
implicit def float2taxrate(f: Float) = TaxRate(BigDecimal(f))
scala> withTax(15.00)(0.15f)
res1: scala.math.BigDecimal = 17.250000089406967200
Aquí, llamamos a una tasa de impuesto explícito de 0.15f
. Eso no coincide con el parámetro, que debe ser del tipo TaxRate
, pero el compilador ve que podemos convertir los flotantes en tasas impositivas usando el implícito float2taxrate
. Entonces lo hace por nosotros, llamando al withTax(15.00)(float2taxrate(0.15f))
Ahora el otro ejemplo.
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 no tiene un método rounded
, por lo withTax(15.00)(0.15f)
no debería ser capaz de llamar a uno (ya que devuelve un BigDecimal
). Pero hemos definido un Currency
que tiene un método rounded
y una conversión a Currency
, por lo que la conversión implícita completa todos los detalles: bigdec2currency(withTax(15.00)(0.15f)).rounded
.
En el caso de la conversión de Int
a BigInt
, el compilador lo usará cuando, por ejemplo, intente agregar 7 + BigInt(5)
. Esto no va a funcionar normalmente-- 7
es un Int
y Int
no sabe cómo agregarse a sí mismo a BigInt
. Pero BigInt
tiene un método +
que puede agregarse a otro BigInt
. Y el compilador ve que si pudiera convertir 7
a BigInt
, podría usar ese método. La conversión implícita permite esa conversión, por lo que traduce 7 + BigInt(5)
en int2bigInt(7)+BigInt(5)
.
(Nota: int2bigInt
se define dentro de BigInt
, por lo que para usarlo hay que import BigInt._
Y a su vez se remite al método apply(i: Int)
del objeto BigInt
, que es lo que le permite escribir BigInt(5)
y tienen que trabajar (en lugar de. tener que pasar una cadena como con BigInteger
en Java).)
Creo que se refiere a las conversiones implícitas. Los parámetros implícitos son algo ligeramente diferente. – GClaramunt
[Programación en Scala 1st Edition] (http://www.artima.com/pins1ed/): [Conversiones implícitas y parámetros] (http://www.artima.com/pins1ed/implicit-conversions-and-parameters). html) – user272735