11

在 Scala 中,可以通过将字符串视为 Seq[Char] 来基于字符串的单个字符来制定模式。

A Tour of Scala中提到了此功能的一个示例

这是那里使用的示例代码:

object RegExpTest1 extends Application {
 def containsScala(x: String): Boolean = {
   val z: Seq[Char] = x
   z match {
      case Seq('s','c','a','l','a', rest @ _*) =>
                println("rest is "+rest)
                true
      case Seq(_*) =>
                false
   }
 }

}

我遇到的问题是代码段的第三行:

val z: Seq[Char] = x

为什么这种演员阵容是必要的?在所有情况下(包括模式匹配),字符串不应该表现得像 Seq[Char] 吗?但是,如果没有这种转换,代码片段将无法工作。

4

3 回答 3

19

问题和评论中确实存在对术语的滥用。这段代码没有演员表,尤其是“所以基本上,这是对 Java 互操作性的重大让步,牺牲了一些类型的健全性”在现实中没有根据。

Scala 演员表如下所示x.asInstanceOf[Y]
你在上面看到的是一个作业:val z: Seq[Char] = x

此分配是合法的,因为存在从Stringto的隐式转换Seq[Char]。我再次强调,这不是演员表。强制转换是一个在运行时可能会失败的任意断言。隐式转换不可能失败。

依赖类型之间的隐式转换以及原始问题的答案的问题是,只有在原始值不进行类型检查时才会发生隐式转换。由于在字符串上匹配是完全合法的,因此不会发生转换,匹配就会失败。

于 2009-04-12T00:01:04.153 回答
12

不是 100% 确定这是否正确,但我的直觉是,如果没有这种显式转换,您将与 进行模式匹配java.lang.String,这不是您想要的。

显式转换强制 Scala 编译器使用Predef.stringWrapper隐式转换;因此,随着RichString extends Seq[Char],您可以进行模式匹配,就好像字符串是一个字符序列一样。

于 2009-04-11T18:25:48.763 回答
7

我将回应 andri 所说的一切。为了互操作性,Scala 字符串是java.lang.Strings。在中,有一个从toPredef的隐式转换,它实现了.StringRichStringSeq[Char]

编码模式匹配的一种可能更好的方法,不需要中间 valz来保存Seq[Char]

def containsScala(x: String): Boolean = {
  (x: Seq[Char]) match {
    ...
  }
}
于 2009-04-11T21:05:26.900 回答