作为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
似乎匹配应该返回一个布尔值,无论是否使用捕获。 这是怎么回事?
答案 0 :(得分:8)
在match
块中,nuc
是模式变量,并未引用封闭范围中的nuc
。这使得默认情况无法访问,因为简单模式nuc
将匹配任何内容。
nuc
上的一对空括号将使语法糖工作并在正则表达式上调用unapplySeq
方法:
myString match {
case nuc() => println("dna")
case _ => println("not dna")
}
避免此陷阱的一种方法是将nuc
重命名为Nuc
。以大写字母开头使其成为一个稳定的标识符,因此它引用封闭范围中的Nuc
,而不是被编译器视为模式变量。
val Nuc = "[ACGT]+".r
myString match {
case Nuc => println("dna")
case _ => println("not dna")
}
以上内容将打印"not dna"
,因为我们只是将Nuc
与myString
进行比较,但它们并不相同。这是一个错误,但可能不那么令人困惑!
在这种情况下,添加括号也会产生预期的效果:
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))