2011-11-06 17 views

Respuesta

11

No puede Parche mono, que cambia los objetos que ya existen. Sin embargo, puede escribir una conversión implícita que actúa de la misma manera (y es posiblemente más seguro) en la mayoría de los casos.

En primer lugar, con unless como está escrito, no necesita que sea un método de cada clase. Solo pégalo en algún objeto e importa.

object Utility { 
    def unless(condition: => Boolean)(body: => Unit):Unit = if(!condition) body 
} 

import Utility._ 

Pero a veces se hace quieren que ella actúe como un método en una clase. Por ejemplo, a menudo escribir

option.map(x => f(x)).getOrElse(default) 

que podría escribirse de forma más compacta como un pliegue:

option.fold(default)(x => f(x)) 

excepto que Option no tiene doblez. Entonces yo:

class OptionWrapper[A](o: Option[A]) { 
    def fold[Z](default: => Z)(action: A => Z) = o.map(action).getOrElse(default) 
} 
implicit def option_has_utility[A](o: Option[A]) = new OptionWrapper(o) 

(esto se llama el patrón "pimp my library"). Ahora puedo usar fold en mi corazón, ya que cada vez que hay una opción y llamo al método fold, el compilador se da cuenta de que no hay un método fold y busca cualquier forma en que pueda convertir la clase en algo que sí tiene una fold. Existe un método de este tipo, y la nueva clase aplica a la opción existente exactamente lo que desea de un método fold en la clase misma.

+0

En cuanto a "posiblemente más seguro", vamos a discutir. ¿Cómo es una conversión implícita más segura que el parche de mono? Aún permite que los objetos usen métodos que la clase original no tenía disponibles. –

+0

@ DanBurton ¿por qué no lo hace como una pregunta? –

+5

@ Dan Burton - Con el parche de mono, puede tener una combinación de objetos, algunos de los cuales tienen un método y otros no; esto plantea problemas en los que espera que un objeto tenga un método pero no ha sido parcheado (o la versión incorrecta ha sido parcheada). Con las conversiones implícitas, tiene seguridad de tipo de tiempo de compilación: se garantiza que las clases tienen los métodos que tienen y se garantiza que las conversiones funcionarán. –

2

Si todas sus clases están bajo un solo paquete (y recordar paquetes can be nested en Scala!), Puede colocar sus definiciones en un package object.

Cuestiones relacionadas