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

发布于 2024-07-16 17:53:07 字数 678 浏览 5 评论 0原文

在 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] 吗? 但是,如果没有这种转换,代码片段将无法工作。

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

An example of this feature is mentioned in 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

少女七分熟 2024-07-23 17:53:07

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

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

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

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

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.

A scala cast looks like this: x.asInstanceOf[Y].
What you see above is an assignment: 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.

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.

向日葵 2024-07-23 17:53:07

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

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

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.

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.

禾厶谷欠 2024-07-23 17:53:07

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

一种可能更好的模式匹配编码方式,无需中间 val z 来保存 Seq[Char]

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

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].

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

def containsScala(x: String): Boolean = {
  (x: Seq[Char]) match {
    ...
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文