Scala 的双字符串插值不适用于转义字符

问题描述 投票:0回答:1

我正在尝试使用双/反向字符串插值将字符串解构为值,但如果字符串包含“ ”或“ ”等转义字符,我就会遇到问题 '.

作为参考,我正在谈论李浩毅在7387中在scala 2.13中添加的这个功能。

PR 中的这个示例有效:

val s"Hello, $name" = "Hello, James"
println(name)  // "James"

但是加上 ' ' 或 ' ' 进入它打破了它:

// '\t'
val s"Hello\t$name" = "Hello\tJames"
// scala.MatchError: Hello James (of class java.lang.String)

// '\n'
val s"Hello\n$name" = "Hello\nJames"
// scala.MatchError: Hello     <---- note error is different to others

// '\r'
val s"Hello\r$name" = "Hello\rJames"
// James (of class java.lang.String)  <---- note weird error that gets thrown here

// '\"'
val s"Hello\"$name" = "Hello\"James"
// scala.MatchError: Hello"James (of class java.lang.String)

// '\\'
val s"Hello\\$name" = "Hello\\James"
// scala.MatchError: Hello\James (of class java.lang.String)

上面是在 WSL 上使用 java 8 在 scala 2.13 的 ammonite 上运行的。我在 scala 3 和 sbt 项目中遇到了类似的问题。

这对我来说不是一个障碍,但我发现这个功能很有用并且想更好地理解它。我能找到的关于此功能的唯一文档是原始 PR 以及 scala 2.13 发行说明中的非常简短的提及。

一些问题:

  1. 这是预期行为还是错误或未定义? PR 没有定义这些边缘情况的行为。
  2. 有任何已知的解决方法吗?
  3. 此功能的官方名称是什么?在 PR 上,Haoyi 将其称为“简单字符串插值器的对偶”。知道它的正确名称将有助于我搜索它。
  4. 还有其他官方文档吗?

感觉像是一个错误,因为普通插值支持转义,并且此功能是它的“双重”:

val name = "James"

s"Hello\t$name"
// "Hello\tJames"

谢谢!

scala string-interpolation
1个回答
0
投票
  1. 这是预期行为还是错误或未定义? PR 没有定义这些边缘情况的行为。

这被视为一个错误 - 请参阅问题 12893

很快就修复了 - 请参阅PR 10570


  1. 有任何已知的解决方法吗?

既然错误已经修复,就不再需要太多解决方法了。

但为了完整起见,按照@Gaël的建议,可以使用正则表达式:

// Scala 2.13
val afterHello = "Hello\t(.*)".r

val afterHello(name) = "Hello\tJames"
// `name` set to "James"

在 scala 3 中,您将收到编译器警告,提示匹配不详尽。要删除它,请添加

unchecked
,如下所示:

// Scala 3
val afterHello(name) = "Hello\tJames": String @ unchecked

或者使用值得信赖的

split
:

val Array(_, name) = "Hello\tJames".split('\t')

出于某种原因,这个不需要

unchecked


  1. 此功能的官方名称是什么?在 PR 上,Haoyi 将其称为“简单字符串插值器的对偶”。知道它的正确名称将有助于我搜索它。

我在issue 12893问过这个问题。赛斯说:

在某种程度上,它只是一种方法而不是“功能”;字符串插值是特征,各个插值器是方法。


  1. 还有其他官方文档吗?

除了原始PR之外,似乎没有任何官方文档。

问题 12893 提供了一些关于 插值模式如何转换的官方文档的链接。这些对于一般背景很有帮助,但与此功能无关。

© www.soinside.com 2019 - 2024. All rights reserved.