我尝试使用双重/反向字符串插值将字符串分解为值,但如果字符串包含转义字符(如“\t”或“\n”),我会遇到问题。
作为参考,我说的是李浩毅在7387中的scala 2.13中添加的这个特性。
这个例子来自PR作品:
val s"Hello, $name" = "Hello, James"
println(name) // "James"
字符串
但是,将"\t“或”\n“放入其中会将其破坏:
// '\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)
型
上面的代码是在java 8的WSL上为scala 2.13运行的。我在scala 3和sbt项目中遇到了类似的问题。
这对我来说不是一个拦截器,但我觉得这个功能很有用,我想更好地理解它。我能找到的关于这个功能的唯一文档是在原始PR和scala 2.13 release notes中的一个非常简短的提到。
有些疑问:
1.这是预期的行为、bug还是未定义的行为?PR没有定义这些边缘情况的行为。
1.是否有任何已知的变通办法?
1.这个功能的正式名称是什么?在PR上,浩一称之为“简单字符串插值器的对偶”。知道它的正确名称将有助于我搜索它。
1.还有其他官方文件吗?
这感觉像是一个bug,因为普通插值支持转义,而此功能是它的“对偶”:
val name = "James"
s"Hello\t$name"
// "Hello\tJames"
型
谢谢你,谢谢
1条答案
按热度按时间gkl3eglg1#
1.这是预期的行为、bug还是未定义的行为?PR没有定义这些边缘情况的行为。
这被认为是一个漏洞-参见issue 12893。
它很快就被修复了--请参阅PR 10570。
1.是否有任何已知的变通办法?
既然bug已经修复,就不需要太多的变通办法了。
但为了完整起见,正如@Gaël所建议的,可以使用正则表达式:
字符串
在scala 3中,你会得到一个编译器警告,告诉你匹配不是穷举的。
型
或者使用值得信赖的
split
:型
出于某种原因,这个不需要
unchecked
。1.这个功能的正式名称是什么?在PR上,浩一称之为“简单字符串插值器的对偶”。知道它的正确名称将有助于我搜索它。
我在issue 12893中问到这一点.赛斯说:
在某种程度上,它只是一种方法,而不是一种“功能”;字符串插值是功能,单个插值器是方法。
1.还有其他官方文件吗?
除了最初的公关,似乎没有任何官方文件。
Issue 12893提供了一些关于插值模式如何转换的官方文档的链接。这些文档对一般背景很有帮助,但并没有特别涉及到这个功能。