2011-10-25 8 views
5

Considere el siguiente fragmento de código:sobrecarga de métodos cancelar la aplicación en las clases de casos: Scala

case class User(id: Int, name: String) 
object User{ 
    def unapply(str: String) = Some(User(0, str)) 
} 

Scala se queja "Error: No se puede resolver sobrecargado cancelar la aplicación, y el caso de clase de usuario (id: int, str: String)" Es no es posible sobrecargar sin aplicar?

actualización: no aplicar con mayor tamaño de tupla.

case class User(id: Int, str: String) 
object User{ 
    def unapply(s: String) = Some((User(0, s), s, 1234)) 
} 

compilador todavía se queja "No se puede resolver sobrecargado cancelar la aplicación"

Respuesta

8

Su método de cancelar la aplicación no se podría utilizar en la coincidencia de patrones

Funciona con

def unapply(arg: <type to match>) : Option[(<matched fields types>)] 

(sin tupla si sólo uno campo, booleano en lugar de opción si no hay campo).

La cancelar la aplicación estándar de usuario sería (La Scala especificación del lenguaje p. 67)

def unapply(u: User) = 
    if (u eq null) None 
    else Some((u.id, u.name)) 

Es lo que quiere es para que coincida con un usuario con un identificador de cero como en

user match {case User(name) => ....} 

que sería

def unapply(u: User): Option[String] = 
    if(u eq null || u.id != 0) None 
    else Some(u.name) 

Si quieres que una cuerda pueda coincidir como usuario (esto sería bastante extraño)

def unapply(s: String): Option[User] = Some(User(0, s)) 

que trabajaría con

"john" match case User(u) => ... // u is User(0, john) 

supongo que desea que el anterior. En cuyo caso, tanto su aplicación como la estándar son dos métodos con la misma lista de argumentos (un parámetro de usuario), por lo que no son compatibles. Esto puede verse como un poco desafortunado, ya que cuando los métodos se llaman como extractores, el elemento distintivo es en realidad el tamaño de la tupla resultante, no el tipo de los argumentos.

Sin embargo, su método, aunque no es válido como extractor, no causa conflicto. No pude encontrar algo en la especificación que lo prohibiera. Aún así, es inútil y un método útil no sería permitido.

+0

¡Gracias por la explicación detallada! Lo malo ... Me perdí el uso de Some mientras escribía. En realidad estoy buscando el último (extraer usuario de una cadena) - el ejemplo anterior puede ser una simplificación excesiva del escenario real. Usted mencionó que el elemento distintivo es en realidad el tamaño de la tupla, lo intenté solo por el bien de completar agregar más resultados de tupla, pero el compilador no se mueve. ¿Alguna idea de por qué? – Ajay

+2

Me malinterpretas sobre el tamaño de la tupla. Lamentaba que la sintaxis del extractor no lo permita. Pero estoy seguro de que no es así. Por otro lado, si quiere una entrada de Cadena, no entiendo por qué no está permitida.Lo que haría es nombrar el extractor algo más. En el ejemplo al menos, el Usuario es muy engañoso, preferiría 'object NameOfUser {def unapply (s: String): Option [User] ...}'. No sé si tiene sentido en tu código. –

+0

Sí, tienes razón. Voy a nombrar el extractor algo más. Pero aún así el mensaje del compilador no tiene sentido. Por lo menos, debe quedar claro por qué no puedo aplicar la sobrecarga y dónde está el conflicto. – Ajay

1

La razón por la que no puede anular la aplicación (especialmente) es muy probable que tenga el mismo signiture que el creado automáticamente por el objeto complementario de una clase de caso. Recordando que el signiture de una función no toma en cuenta su valor de retorno para el objetivo de anular.

Cuestiones relacionadas