你好Scala程序员
我已经和Scala合作了一个月,但是我对一些基本的东西有问题,我希望你能帮我解决这个问题。
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)
}
}
}
当我这样做时,我得到错误:
pattern type is incompatible with expected type;
found : object PersonClass
required: java.lang.String
case PersonClass => println(string)
如果我然后将模式匹配中的第二行更改为以下内容:
case e:PersonClass => println(string)
然后我得到错误:
error: scrutinee is incompatible with pattern type;
found : PersonClass
required: java.lang.String
case e:PersonClass => println(string)
但是,如果我将字符串定义更改为以下内容,则在两种情况下都可以正常编译。
val string:AnyRef = "hej"
答案 0 :(得分:22)
字符串的推断类型是String。在声明val后就知道了。
正如我们在模式匹配期间已经知道的那样,匹配不是字符串的模式(如PersonClass)是没有意义的,因为它们永远不会匹配。这就是“模式类型与预期类型不兼容;发现:对象PersonClass需要:java.lang.String case PersonClass => println(string)”错误意味着:我们期望一个模式是String的子类,但是发现了一些东西(PersonClass)不是。
强制类型AnyRef时,情况会发生变化。编译器会将字符串视为Anyref,因此扩展AnyRef的模式可能会匹配。 PersonClass是AnyRef,因此您不会收到错误。
答案 1 :(得分:9)
如果您已经有String类型的对象,它永远不会匹配PersonClass类型。它实际上是编译器不会让这些永远不会成功的匹配的功能。
使用Any类型,您只需关闭类型检查。它与此定义不匹配,但编译器无法捕获此问题。
答案 2 :(得分:5)
我假设你正在尝试测试别的东西,但编译器太聪明了,不能让你。
也许你想要这样的东西:
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)
}
}
但正如其他人所指出的那样,如果你实际不需要检查其他类型,编译器会抱怨你正在做的事情毫无意义。也是一件好事:如果您没有编写测试,则可能会遇到难以调试的运行时错误。
答案 3 :(得分: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
}