Jer*_*zig 7 scala pattern-matching
作为这个问题的后续行动
下面是一些使用捕获编译和运行的代码.
val myString = "ACATCGTAGCTGCTAGCTG"
val nucCap = "([ACTG]+)".r
myString match {
case nucCap(myNuc) => println("dna:"+myNuc)
case _ => println("not dna")
}
>scala scalaTest.scala
dna:ACATCGTAGCTGCTAGCTG
Run Code Online (Sandbox Code Playgroud)
这是更简单的代码,没有捕获,不编译.
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
Run Code Online (Sandbox Code Playgroud)
似乎匹配应该返回一个布尔值,无论是否使用捕获.这里发生了什么?
在您的match
块中,nuc
是一个模式变量,并不引用nuc
封闭范围中的变量.这使得默认情况无法访问,因为简单模式nuc
将匹配任何内容.
一对空括号nuc
将使语法糖工作并unapplySeq
在正则表达式上调用方法:
myString match {
case nuc() => println("dna")
case _ => println("not dna")
}
Run Code Online (Sandbox Code Playgroud)
避免这种陷阱的一种方法是重命名nuc
为Nuc
.从大写字母开始使它成为一个稳定的标识符,因此它引用Nuc
封闭范围,而不是被编译器视为模式变量.
val Nuc = "[ACGT]+".r
myString match {
case Nuc => println("dna")
case _ => println("not dna")
}
Run Code Online (Sandbox Code Playgroud)
上面会打印"not dna"
,因为在这里我们只是比较Nuc
到myString
,他们是不相等的.这是一个错误,但可能不那么令人困惑!
在这种情况下,添加括号也会产生预期的效果:
myString match {
case Nuc() => println("dna")
case _ => println("not dna")
}
// prints "dna"
Run Code Online (Sandbox Code Playgroud)
顺便说一句,它不是一个返回的布尔值,但是Option[List[String]]
:
scala> nuc.unapplySeq(myString)
res17: Option[List[String]] = Some(List())
scala> nucCap.unapplySeq(myString)
res18: Option[List[String]] = Some(List(ACATCGTAGCTGCTAGCTG))
Run Code Online (Sandbox Code Playgroud)