匹配字符串的模式为Seq [Char]

时间:2022-09-13 07:48:39

In Scala it is possible formulate patterns based on the invididual characters of a string by treating it as a Seq[Char].

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

An example of this feature is mentioned in A Tour of Scala

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

This is the example code used there:

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

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
   }
 }

}

The problem I have with this is the third line of the snippet:

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

val z: Seq[Char] = x

Why is this sort of cast necessary? Shouldn't a String behave like a Seq[Char] under all circumstances (which would include pattern matching)? However, without this conversion, the code snippet will not work.

为什么这种演员必要?字符串在所有情况下都不应该像Seq [Char]一样(包括模式匹配)?但是,如果没有此转换,代码段将无法使用。

3 个解决方案

#1


Not 100% sure if this is correct, but my intuition says that without this explicit cast you would pattern match against java.lang.String, which is not what you want.

不是100%肯定这是否正确,但我的直觉说如果没有这个显式转换,你会模式匹配java.lang.String,这不是你想要的。

The explicit cast forces the Scala compiler to use Predef.stringWrapper implicit conversion; thus, as RichString extends Seq[Char], you are able to do a pattern match as if the string were a sequence of characters.

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

#2


There is some real abuse of terminology going on in the question and the comments. There is no cast in this code, and especially "So basically, this is a major concession to Java interoperability, sacrificing some type soundness" has no basis in reality.

在问题和评论中有一些真正滥用术语的行为。在这段代码中没有演员,特别是“基本上,这是对Java互操作性的一个主要让步,牺牲一些类型的健全性”在现实中没有根据。

A scala cast looks like this: x.asInstanceOf[Y].
What you see above is an assignment: val z: Seq[Char] = x

scala强制转换如下所示:x.asInstanceOf [Y]。你在上面看到的是一个赋值:val z:Seq [Char] = x

This assignment is legal because there is an implicit conversion from String to Seq[Char]. I emphasize again, this is not a cast. A cast is an arbitrary assertion which can fail at runtime. There is no way for the implicit conversion to fail.

此赋值是合法的,因为存在从String到Seq [Char]的隐式转换。我再次强调,这不是演员。强制转换是一种任意断言,在运行时可能会失败。隐式转换无法失败。

The problem with depending on implicit conversions between types, and the answer to the original question, is that implicit conversions only take place if the original value doesn't type check. Since it's perfectly legal to match on a String, no conversion takes place, the match just fails.

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

#3


I'm going to echo everything that andri said. For interoperability, Scala strings are java.lang.Strings. In Predef, there's an implicit conversion from String to RichString, which implements Seq[Char].

我要回应andri所说的一切。对于互操作性,Scala字符串是java.lang.Strings。在Predef中,有一个从String到RichString的隐式转换,它实现了Seq [Char]。

A perhaps nicer way of coding the pattern match, without needing an intermediate val z to hold the Seq[Char]:

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

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

#1


Not 100% sure if this is correct, but my intuition says that without this explicit cast you would pattern match against java.lang.String, which is not what you want.

不是100%肯定这是否正确,但我的直觉说如果没有这个显式转换,你会模式匹配java.lang.String,这不是你想要的。

The explicit cast forces the Scala compiler to use Predef.stringWrapper implicit conversion; thus, as RichString extends Seq[Char], you are able to do a pattern match as if the string were a sequence of characters.

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

#2


There is some real abuse of terminology going on in the question and the comments. There is no cast in this code, and especially "So basically, this is a major concession to Java interoperability, sacrificing some type soundness" has no basis in reality.

在问题和评论中有一些真正滥用术语的行为。在这段代码中没有演员,特别是“基本上,这是对Java互操作性的一个主要让步,牺牲一些类型的健全性”在现实中没有根据。

A scala cast looks like this: x.asInstanceOf[Y].
What you see above is an assignment: val z: Seq[Char] = x

scala强制转换如下所示:x.asInstanceOf [Y]。你在上面看到的是一个赋值:val z:Seq [Char] = x

This assignment is legal because there is an implicit conversion from String to Seq[Char]. I emphasize again, this is not a cast. A cast is an arbitrary assertion which can fail at runtime. There is no way for the implicit conversion to fail.

此赋值是合法的,因为存在从String到Seq [Char]的隐式转换。我再次强调,这不是演员。强制转换是一种任意断言,在运行时可能会失败。隐式转换无法失败。

The problem with depending on implicit conversions between types, and the answer to the original question, is that implicit conversions only take place if the original value doesn't type check. Since it's perfectly legal to match on a String, no conversion takes place, the match just fails.

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

#3


I'm going to echo everything that andri said. For interoperability, Scala strings are java.lang.Strings. In Predef, there's an implicit conversion from String to RichString, which implements Seq[Char].

我要回应andri所说的一切。对于互操作性,Scala字符串是java.lang.Strings。在Predef中,有一个从String到RichString的隐式转换,它实现了Seq [Char]。

A perhaps nicer way of coding the pattern match, without needing an intermediate val z to hold the Seq[Char]:

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

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