2010-04-16 21 views
8

Hola compañeros Scala programadorespartido costumbre patrón de Scala con java.lang.String y Caso Clase

He estado trabajando con Scala para algunos meses ahora, sin embargo, tengo un problema con un poco de materia propiamente básicas, te estoy esperando lo ayudaré con esto.

case class PersonClass(name: String, age: Int) 

object CaseTester { 
def main(args:Array[String]) 
{ 
    val string = "hej" 
    string match { 
    case e:String => println(string) 
    case PersonClass => println(string) 
    } 
} 
} 

Cuando estoy haciendo como esto me sale error:

pattern type is incompatible with expected type; 
found : object PersonClass 
required: java.lang.String 
case PersonClass => println(string) 

Y si luego cambio de la segunda línea en el patrón de coincidencia a lo siguiente:

case e:PersonClass => println(string) 

entonces consigo el error:

error: scrutinee is incompatible with pattern type; 
found : PersonClass 
required: java.lang.String 
case e:PersonClass => println(string) 

Sin embargo, si cambio la definición de cadena a la siguiente, compila bien en ambos casos.

val string:AnyRef = "hej" 
+0

Originalmente me encontré con el problema al intentar hacer una clase el caso de que también debe ser capaz de ser un extractor, sin embargo cuando pienso Eso no tiene mucho sentido :) – Stefan

+0

Usted no puede coincidir con una clase como eso. 'case PersonClass =>' solo funciona si 'PersonClass' es un objeto. Para hacer coincidir las clases, puede asignar una variable local: 'case e: String =>' o descomprimir si es una tupla o una clase de caso: '(3, 4) match {case (a, b) =>' – Ryan

Respuesta

21

El tipo inferido de cadena es String. Eso se sabe después de la declaración del val.

Como ya lo sabemos durante la coincidencia de patrones, no tiene sentido hacer coincidir patrones que no son cadenas (como su PersonClass), ya que nunca coincidirán. Eso es lo que el "tipo de patrón es incompatible con el tipo esperado; encontrado: el objeto PersonClass requerido: java.lang.String caso PersonClass => println (cadena)" error significa: esperamos un patrón que sea una subclase de String, pero encuentre algo (PersonClass) que no es.

Cuando fuerza el tipo AnyRef, la situación cambia. El compilador tratará la cadena como Anyref, por lo que los patrones que extienden AnyRef pueden coincidir. PersonClass es AnyRef, por lo que no obtienes ningún error.

8

Si ya tiene un objeto de tipo String, nunca coincidirá con un tipo PersonClass. En realidad, es una característica que el compilador no permite que haga estas coincidencias que nunca tendrán éxito.

Con Cualquier tipo, simplemente está desactivando la verificación de tipo. No coincidirá con esta definición, pero el compilador no puede detectar este problema.

5

Supongo que estás tratando de probar algo más, pero el compilador es demasiado inteligente para permitirte.

Tal vez usted quiere algo como esto:

object Test { 
    case class Person(name: String, age: Int) { } 
    def myPrint(ar: AnyRef) { 
    ar match { 
     case s: String => println(s) 
     case Person(name, age) => println("My name is "+name) 
     case _ => println("I am a mystery!") 
    } 
    } 
    def test = { 
    myPrint("Hello, World") 
    myPrint(Person("John Doe",40)) 
    myPrint(5) 
    } 
} 

pero, como otros han señalado, si no lo hace realidad necesidad de comprobar si los otros tipos, el compilador se quejará de que lo que está hacer es inútil. Algo bueno también: si no estaba escribiendo una prueba, es posible que tenga un error de tiempo de ejecución difícil de depurar.

0
object ws { 

case class PersonClass(name:String,age: Int) 
val p=new PersonClass("ach",25)      

    def string(x: Any) = x match { 
    case x:String => println(x) 
    case x:PersonClass => println(p.name +" "+p.age) 
    }            

    string("aa")         //> aa 
    string(p)         //> ach 25 

} 
Cuestiones relacionadas