2011-10-31 20 views
7

que tiene la clase siguiente:Scala: dos argumento implícito con la misma declaración

class Example(implicit doSomething1: (Double, Double) => Double, implicit doSomething2: (Double, Double) => Double) 
{ 
    //.. 
} 

al ver que el constructor tiene dos argumentos implícitos (funciones) con la misma declaración. Pero quiero "inyectar" dos definiciones diferentes. ¿Es esto posible de una manera implícita? ¿O solo es posible de la manera explícita conocida?

Gracias

Respuesta

0

Escribir

class Example(implicit doSomething1: (Double, Double) => Double, doSomething2: (Double, Double) => Double) 
{ 
    //.. 
} 

Pero si dos argumentos implícitos tienen el mismo tipo, que obviamente tendrán el mismo valor (que todavía puede pasar diferentes argumentos explícitamente).

8

Si el compilador busca un implicit (Double, Double) => Double en ámbito implícito, o bien hay exactamente uno con mayor prioridad y lo elegirá las dos veces, o no (no hay ninguno en alcance implícito, o más de uno con la prioridad más alta) y habrá un error por falta de un valor implícito.

Si desea distinguir, puede tener dos tipos diferentes, ambos extendiendo Function2 [Double, Double, Double]. Por ejemplo

trait Addition extends Function[Double, Double, Double] 
trait Multiplication extends Function[Double, Double, Double] 
class Example(implicit addition: Addition, implicit multiplication: Multiplication) 

Esto puede estar bien, tiene sentido elegir ambas operaciones de forma independiente. Si las dos opciones necesitan ser conistent, podría tener más sentido tener sólo un rasgo tanto con la operación

trait Ring { 
    def add(x: Double, y: Double): Double 
    def mult(x: Double, y: Double): Double 
} 
// or `case class Ring(
//  addition: (Double, Double) => Double, 
//  multiplication: (Double, Double) => Double) 
class Example(implicit ring: Ring) 

Por último, todo esto es útil sólo si obtiene las operaciones apropiadas en su alcance implícito "de forma natural". Si usted tiene que hacer que sean implícita cada vez que se crea un ejemplo, al igual que en

implicit val addition = ... 
implicit val multiplication = 
new Example 

que podría así ser explícita.

Además, si se espera que la mayoría de las llamadas a trabajar con el mismo valor, y lo que desea es cambiar algunos de ellos, es posible que en lugar ir para argumentos con valores por defecto

class Example(doSomething1 : (Double, Double) => Double = <default value>, doSomething2 ...) 

Usted puede incluso tener ambos, un argumento implícito con el valor predeterminado. Si lo hace, el valor predeterminado se utiliza cuando no se encuentra implícito.

Cuestiones relacionadas