2010-04-16 125 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 

}