2010-04-16 126 views
8

你好老乡斯卡拉程序员斯卡拉习惯模式匹配与java.lang.String中和案例类

我一直在斯卡拉工作现在有些一个月,但是我有一些适当的基本的东西出了问题,我希望你将帮助我摆脱困境。

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

原来我遇到的问题,同时试图做的也应该能够成为一个提取的情况下类,但是当我想它不作出了很大的意义:) – Stefan 2010-04-16 14:30:06

+0

不能匹配类像那样。 'PersonClass =>'仅当PersonClass是一个对象时才起作用。要匹配类,你要么分配给一个局部变量:'case e:String =>'或者解包它是一个元组还是case类:'(3,4)match {case(a,b)=>' – Ryan 2013-12-27 18:14:05

回答

21

字符串的推断类型是字符串。这是val的宣言后知道的。

正如我们在模式匹配过程中已经知道的那样,匹配不是字符串的模式(比如PersonClass)是没有意义的,因为它们永远不会匹配。这就是“模式类型与预期类型不兼容;找到:object PersonClass必需:java.lang.String case PersonClass => println(string)”错误意味着:我们期望一个模式是String的子类,但是发现了一些PersonClass)不是。

当您强制使用AnyRef类型时,情况会发生变化。编译器会将字符串视为Anyref,所以扩展AnyRef的模式可能会匹配。 PersonClass是AnyRef,所以你不会错误。

8

如果你已经有一个String类型的对象时,它永远不会匹配一个类型PersonClass。这实际上是编译器不会让这些匹配永远不会成功的功能。

随着任何类型,你只是简单地把类型检查。它不符合这个定义,但编译器无法解决这个问题。

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

但正如其他人所指出的,如果你不实际上需要检查的其他类型,编译器会抱怨你在做什么这样做毫无意义。也是一件好事:如果你没有编写测试,你可能会遇到难以调试的运行时错误。

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 

}