Si el método tiene sólo uno o dos por defecto los parámetros que se pueden ajustar a null
considerar este patrón:
// please note that you must specify function return type
def aMethod (x:String = "asdf"):String = if (x==null) aMethod() else {
// aMethod body ...
x
}
hay algunas ventajas:
- La definición del método indica claramente predeterminado del parámetro valor.
- El valor predeterminado correcto puede ser elegido por las herramientas de Scala, incluido ScalaDoc.
- No hay necesidad de definir un valor adicional para sustituir el parámetro original dentro del cuerpo del método, hay menos espacio para errores, es más fácil razonar.
- El patrón es bastante conciso.
Además, considere la situación siguiente:
trait ATrait {
def aMethod (x:String = "trait's default value for x"):String
}
class AClass extends ATrait {
....
}
Claramente, aquí tenemos que extender el rasgo, al tiempo que preserva el valor predeterminado original.Cualquiera de los patrones que supongan poner inicialmente el parámetro a null
seguido de un valor por defecto de verificación y la real se romperá el contrato establecido por el rasgo:
class AClass extends ATrait {
// wrong, breaks the expected contract
def aMethod(x: String = null):String = {
val xVal = if (x == null) "asdf" else x
...
}
}
De hecho, en este escenario, la única manera de preservar el valor original de ATrait
serán los siguientes:
class AClass extends ATrait {
override def aMethod (x:String):String = if (x==null) aMethod() else {
... // x contains default value defined within ATrait
}
}
Sin embargo, en el escenario cuando hay más de uno o dos parámetros por defecto que se pueden ajustar a null
el patrón empieza a ser bastante desordenado:
// two parameters
def aMethod (x:String = "Hello",y:String = "World"):String =
if (x==null) aMethod(y=y) else
if (y==null) aMethod(x=x) else {
// aMethod body ...
x + " " + y
}
// three parameters
def aMethod (x:String = "Hello",y:String = " ",z:String = "World"):String =
if (x==null) aMethod(y=y,z=z) else
if (y==null) aMethod(x=x,z=z) else
if (z==null) aMethod(x=x,y=y) else {
// aMethod body ...
x + y + z
}
Sin embargo, al anular un contrato existente, esta podría ser la única forma de respetar los valores predeterminados originales.
¿Hay alguna manera de convertir implícitamente a una opción? Claro que podría escribir mi propia definición, ¿pero ya hay una en la API? –
@JohnSmith: quieres decir algo como: 'implicit def obj2Option [T] (t: T) = Option (t)'? Creo que esto es demasiado frágil/peligroso para ser parte de las conversiones implícitas estándar, no sé de ninguna. –
@TomaszNurkiewicz por favor vea mi respuesta, ya que esta solución, en un examen más detallado, tendrá un impacto negativo en las herramientas de desarrollo de Scala y tendrá el potencial de romper el código cuando se trate de la herencia. –