2011-10-25 98 views
7

匹配作爲後續this問題正則表達式格局,斯卡拉第二部分

下面是一些編譯和運行正常,使用捕捉代碼。

val myString = "ACATCGTAGCTGCTAGCTG" 

val nucCap = "([ACTG]+)".r 

myString match { 
    case nucCap(myNuc) => println("dna:"+myNuc) 
    case _ => println("not dna") 
} 

>scala scalaTest.scala 
dna:ACATCGTAGCTGCTAGCTG 

這裏是更簡單的代碼,沒有捕獲,不編譯。

val myString = "ACATCGTAGCTGCTAGCTG" 

val nuc = "[ACGT]+".r 

myString match { 
    case nuc => println("dna") 
    case _ => println("not dna") 
} 

>scala scalaTest.scala 
scalaTest.scala:7: error: unreachable code 

似乎匹配應該返回布爾值,無論是否使用捕獲。 這是怎麼回事?

回答

8

在您的match區塊中,nuc是一個模式變量,並且在封閉範圍內沒有引用nuc。這使得默認情況下無法訪問,因爲簡單模式nuc將匹配任何內容。

一對空括號對nuc將使語法糖工作,並調用unapplySeq方法的正則表達式:爲了避免這一缺陷

myString match { 
    case nuc() => println("dna") 
    case _ => println("not dna") 
} 

一種方法是重命名nucNuc。以大寫字母開頭使其成爲一個穩定的標識符,以便它引用封閉作用域中的Nuc,而不是被編譯器視爲模式變量。

val Nuc = "[ACGT]+".r 
myString match { 
    case Nuc => println("dna") 
    case _ => println("not dna") 
} 

上面會打印"not dna",因爲在這裏我們簡單地比較NucmyString,他們是不相等的。這是一個錯誤,但也許不那麼令人困惑!

添加括號將在這種情況下也預期的效果:順便問一下

myString match { 
    case Nuc() => println("dna") 
    case _ => println("not dna") 
} 
// prints "dna" 

,它不是被返回一個布爾值,而是一個Option[List[String]]

scala> nuc.unapplySeq(myString) 
res17: Option[List[String]] = Some(List()) 
scala> nucCap.unapplySeq(myString) 
res18: Option[List[String]] = Some(List(ACATCGTAGCTGCTAGCTG)) 
+0

不是挑剔的,但爲什麼它說默認情況是不可達的(case _ => println(「不是dna」)) –

+0

我錯過了我的答案 - 現在更新它來解釋這一點。 –