Scala中的正则表达式和模式匹配第二部分

Scala中的正则表达式和模式匹配第二部分,scala,pattern-matching,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:ACATCGTAGCTGCTAGCT

作为问题的后续行动

下面是一些使用捕获正确编译和运行的代码

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
似乎无论是否使用捕获,匹配都应返回布尔值。
这里发生了什么?

match
块中,
nuc
是一个模式变量,不引用封闭范围中的
nuc
。这使得默认情况不可访问,因为简单模式
nuc
将匹配任何内容

nuc
上的一对空括号将使语法糖起作用,并调用正则表达式上的
unplyseq
方法:

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")
}
上面将打印“非dna”,因为这里我们只是将
Nuc
myString
进行比较,它们并不相等。这是一个错误,但可能是一个更容易混淆的错误

在这种情况下,添加括号也会产生预期效果:

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

顺便说一下,返回的不是布尔值,而是一个
选项[List[String]]

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

不是吹毛求疵,但为什么它会说默认情况是不可访问的(case=>println(“notdna”))