2011-06-28 17 views
13

Objeto L1 debajo funciona. Puedo "crear" un L1 pasando varargs, lo cual es bueno, pero me gustaría poder asignar un L1 usando la misma sintaxis. Desafortunadamente, la forma en que lo hice aquí requiere la sintaxis más fea de anidar un Array dentro del L1.Scala: ¿puede deshacer la aplicación de varargs de devolución?

object L1 { 
    def apply(stuff: String*) = stuff.mkString(",") 
    def unapply(s: String) = Some(s.split(",")) 
} 
val x1 = L1("1", "2", "3") 
val L1(Array(a, b, c)) = x1 
println("a=%s, b=%s, c=%s".format(a,b,c)) 

que intentaron lograr esto en lo que parece una forma obvia, como en L2 a continuación:

object L2 { 
    def apply(stuff: String*) = stuff.mkString(",") 
    def unapply(s: String) = Some(s.split(","):_*) 
} 
val x2 = L2("4", "5", "6") 
val L2(d,e,f) = x2 
println("d=%s, e=%s, f=%s".format(d,e,f)) 

Pero esto da el error:

error: no `: _*' annotation allowed here 
(such annotations are only allowed in arguments to *-parameters)`. 

¿Es posible que unapply a usar varargs de esta manera?

Respuesta

21

Creo que lo que quieres es unapplySeq. Jesse Eichar tiene una buena redacción en unapplySeq

scala> object L2 { 
    |  def unapplySeq(s: String) : Option[List[String]] = Some(s.split(",").toList) 
    |  def apply(stuff: String*) = stuff.mkString(",") 
    | } 
defined module L2 

scala> val x2 = L2("4", "5", "6") 
x2: String = 4,5,6 

scala> val L2(d,e,f) = x2 
d: String = 4 
e: String = 5 
f: String = 6 
+0

¡Perfecto! ¡Gracias! – dhg

Cuestiones relacionadas