2011-02-15 11 views
16

Intenté reemplazar mi verificación isInstanceOf con una coincidencia, pero no funciona.Error de coincidencia de Scala

En mi método hago una comprobación de un nodo de árbol, si es una hoja, quiero devolverlo dentro de un Vector de inmediato, si no, continúo con el método.

Así que en principio había:

//code here 
    if (common.isInstanceOf[LeafNode]) { 
     return Vector(common.asInstanceOf[LeafNode].data) 
    } 
    //code here 

Luego trató de reemplazarlo con:

//code here 
    common match { 
     case leaf: LeafNode => return Vector(leaf.data) 
    } 
    //code here 

pero consigo scala.MatchError.

Respuesta

21

Obtiene un MatchError en el caso en que su common no es un LeafNode. Sus expresiones if y match no son equivalentes. Creo que la forma más directa para que sean equivalente es:

common match { 
    case leaf: LeafNode => return Vector(leaf.data) 
    case _ => 
} 

pero recomiendo buscando en todo el bloque de código y hacer ejercicio son la manera más funcional para hacer este trabajo. Es decir, sin el return en el medio. Recuerde que el partido es una expresión, por lo que algo como esto puede ser posible:

def foo = { 
    //code here 
    common match { 
    case leaf: LeafNode => Vector(leaf.data) 
    case notLeaf: Branch => //code here 
    } 
} 
+0

Gracias, intentaré volver a trabajarlo – drozzy

+1

¿Por qué usó return? – raam86

5

El problema es que el conjunto de casos en su bloque match no es exhaustivo; si common es cualquier cosa menos LeafNode, se lanzará un MatchError. Puede resolver esto por tener un cajón de sastre caso así:

common match { 
    case leaf: LeafNode => return Vector(leaf.data) 
    ... // other cases 
    case other => ... // what to do if nothing else matches 
} 

Esto es análogo al caso default en una sentencia switch de Java. El caso other se denomina "patrón irrefutable" porque no tiene características; no requiere un tipo o constructor en particular, por lo que siempre coincidirá con cualquier elemento que le atraviese. El nombre de la variable no tiene que ser other, puede ser cualquier cosa que desee, o incluso _ ... de hecho, no necesita vincular una nueva variable aquí ya que será idéntica a common.

En un punto de estilo, generalmente es mala forma poner declaraciones de devolución dentro de un bloque match; todo el bloque es una expresión que evalúa uno de sus casos, así que solo devuelve la expresión completa. Además, no es necesario utilizar la palabra clave return, ya que la última expresión de una definición de función se utilizará como resultado.

+0

buen punto sobre las devoluciones, gracias – drozzy

+0

de hecho, si usted tiene una sentencia return en su función, los Scala 2.9 del compilador le obliga para indicar explícitamente el tipo de devolución de la función. No estoy seguro acerca de las versiones anteriores, aunque – Aaron

Cuestiones relacionadas