tutorial reservadas programacion palabras listas español calculadora scala scala-2.8 default-value named-parameters

reservadas - ¿Es posible que un valor de argumento opcional dependa de otro argumento en Scala?



programacion en scala (3)

Alguien sabe si algo como esto es posible en Scala:

case class Thing(property:String) def f(thing:Thing, prop:String = thing.property) = println(prop)

El código anterior no compila; dando el error de error: not found: value thing en thing.property

A continuación se muestra el comportamiento esperado:

f(Thing("abc"), "123") // prints "123" f(Thing("abc")) // prints "abc"

Me doy cuenta de que podría hacer que el argumento prop una Option[String] y realizar la comprobación de la definición de la función, pero me preguntaba si habría alguna forma de evitarlo con el nuevo soporte de argumento por nombre / predeterminado en 2.8.0.


Esto es exactamente para lo que está la Option . Puede usar el método getOrElse antes de la llamada al método o dentro del método f .

scala> val abc = Some("abc") abc: Some[java.lang.String] = Some(abc) scala> val none: Option[String] = None none: Option[String] = None scala> println(abc getOrElse "123") abc scala> println(none getOrElse "123") 123 scala> def f(o: Option[String]) = println(o getOrElse "123") f: (o: Option[String])Unit scala> f(abc) abc scala> f(none) 123

Oh, aquí hay algo que podrías hacer a través de argumentos predeterminados:

scala> case class Thing(property: String = "123") defined class Thing scala> def f(t: Thing) = println(t.property) f: (t: Thing)Unit scala> f(Thing("abc")) abc scala> f(Thing()) 123

El comportamiento esperado se puede lograr con una sobrecarga simple. Necesitaba poner el método en un object porque parece que el REPL no permite declaraciones de funciones sobrecargadas directamente:

scala> object O { def overloaded(t:Thing) = println(t.property) def overloaded(t:Thing,s:String) = println(s) } defined module O scala> O.overloaded(Thing("abc"), "123") 123 scala> O.overloaded(Thing("abc")) abc


Otra solución simple es simplemente sobrecargar el método:

case class Thing (property: String) def f(thing: Thing, prop: String) = println(prop) def f(thing: Thing) = f(thing, thing.property)


Sí, es posible en Scala 2.8. Aquí hay una cita del documento de diseño "Argumentos con nombre y predeterminados en Scala 2.8" :

Como el alcance de un parámetro se extiende a todas las listas de parámetros posteriores (y al cuerpo del método), las expresiones predeterminadas pueden depender de los parámetros de las listas de parámetros anteriores (pero no de otros parámetros en la misma lista de parámetros). Tenga en cuenta que cuando se utiliza un valor predeterminado que depende de parámetros anteriores, se utilizan los argumentos reales, no los argumentos predeterminados.

def f(a: Int = 0)(b: Int = a + 1) = b // OK

Y otro ejemplo:

def f[T](a: Int = 1)(b: T = a + 1)(c: T = b) // generates: // def f$default$1[T]: Int = 1 // def f$default$2[T](a: Int): Int = a + 1 // def f$default$3[T](a: Int)(b: T): T = b

De acuerdo con esto, su código puede verse como sigue:

scala> case class Thing(property:String) defined class Thing scala> def f(thing:Thing)(prop:String = thing.property) = println(prop) f: (thing: Thing)(prop: String)Unit scala> f(Thing("abc"))("123") 123 scala> f(Thing("abc"))() abc