开发者

Scala wont pattern match with java.lang.String and Case Class

开发者 https://www.devze.com 2022-12-26 21:13 出处:网络
Hello fellow Scala Programmers I have been working with Scala for some month now, however I have a problem with some properly basic stuff, I am hoping you will help my out with it.

Hello fellow Scala Programmers

I have been working with Scala for some month now, however I have a problem with some properly basic stuff, I am hoping you will help my out with it.

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)
  }
 }
}

When I am doing like this I get error:

pattern type is incompatible with expected type;
found   : object PersonClass
required: java.lang.String
case 开发者_开发百科PersonClass => println(string)

And if I then change the second line in the pattern matching to the following:

case e:PersonClass => println(string)

I then get the error:

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

However if I change the string definition to the following it compiles fine in both cases.

val string:AnyRef = "hej"


The inferred type of string is String. That is known after the declaration of the val.

As we already know it during pattern matching it doesn't make sense to match patterns that are not Strings (like your PersonClass), as they will never match. That's what the "pattern type is incompatible with expected type; found : object PersonClass required: java.lang.String case PersonClass => println(string)" error means: we expect a pattern that is a subclass of String, but found something (PersonClass) which is not.

When you force the type AnyRef the situation changes. The compiler will treat string as Anyref, so patterns that extend AnyRef might match. PersonClass is AnyRef, so you don't get error.


If you already have an object of type String it will never match a type PersonClass. It's actually a feature that the compiler does you not let do these matches that will never succeed.

With the Any type you are simply turning the type check off. It won't match with this definition but the compiler can't catch this problem.


I assume you're trying to test something else, but the compiler is too smart to let you.

Maybe you want something like this:

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)
  }
}

but as others have pointed out, if you don't actually need to check for the other types, the compiler will complain that what you're doing is pointless. A good thing, too: if you weren't writing a test, you might have a hard-to-debug runtime error.


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

}
0

精彩评论

暂无评论...
验证码 换一张
取 消