2009-04-11 58 views
10

在Scala中,可以通过将字符串的字符串视为Seq [Char]来制定基于字符串的字符的模式。将字符串匹配为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]?但是,如果没有这种转换,代码片段将不起作用。

回答

11

不是100%确定这是否正确,但我的直觉表明,如果没有这个明确的演员阵容,你会模式匹配java.lang.String,这不是你想要的。

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

+0

这使得很多的意义,基本上是我一直在猜测。但是,我没有找到隐式转换器。感谢您指出。所以基本上,这是Java互操作性的一个重要让步,牺牲了某种类型的健全性。 – 2009-04-11 19:12:23

+2

没有类型的健全性丢失。隐式转换只是插入函数调用的编译器,类似于val z:Seq [Char] = string2Seq(x) – 2009-04-11 23:57:41

7

我要回应安德里所说的一切。为了互操作性,Scala字符串是java.lang.String s。在Predef中,存在从StringRichString的隐式转换,其实现Seq[Char]

一个可能被更好的编码模式匹配,而不需要中间VAL z持有的方式Seq[Char]

def containsScala(x: String): Boolean = { 
    (x: Seq[Char]) match { 
    ... 
    } 
} 
17

有术语的一些真正的滥用问题和意见回事。这段代码没有强制转换,特别是“基本上,这是Java互操作性的一个重要让步,牺牲了某种类型的健全性”实际上没有任何基础。

斯卡拉演员看起来像这样:x.asInstanceOf[Y]
什么你在上面看到的是一个任务:val z: Seq[Char] = x

这种分配是合法的,因为有一个隐式转换从StringSeq[Char]。我再次强调,这不是一个演员。强制转换是可以在运行时失败的任意断言。隐式转换无法失败。

取决于类型之间的隐式转换以及对原始问题的答案的问题是,只有在原始值不检查类型时才会发生隐式转换。因为在String上匹配是完全合法的,所以不会发生转换,匹配只会失败。