热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

五金手册_五金反引号

五金手册五种琴弦从Java1.0开始,我们就有了字符串文字likethis。我们还想要其他什么字符串?其他编程语言为我们提供:表达式插
五金手册

五金手册

五种琴弦

从Java 1.0开始,我们就有了字符串文字"like this" 。 我们还想要其他什么字符串? 其他编程语言为我们提供:

  • 表达式插值: s"I am ${age - 10} years old."
  • 插值格式: f"Price: $price%8.2f"
  • 具有在编译时检查的内部语法的字符串: r"[0-9]+([.,][0-9]*)?xml"The Java home page"
  • 未转义反斜杠的原始字符串: raw"\.*"
  • 可以包含换行符的多行字符串:

    """
    +-----+
    | Cay |
    +-----+
    """

在这里,我使用的语法让人想起Scala进行演示。 其他语言则做出了不同的选择。 例如,Javascript使用反引号进行插值。

我最想在Java中拥有以下哪些功能? 对我而言,这将是编译时语法检查。 现在,IDE可以进行有根据的猜测,例如特定字符串很可能是正则表达式,如果格式错误,则会发出警告。 但是,如果是编译时错误,那就更好了。

当然,这是一个难题。 除了注释处理之外,没有其他在编译时添加可插入检查的机制。 可以提供检查字符串内容的注释,而Checker Framework确实可以做到这一点。 但是您注释变量,而不是字符串文字,所以不是同一回事。

如果有一种进行插值和格式化的标准方法,那也很好。 现在,我们有String.formatMessageFormat.format ,它们都是有用的但不兼容。

相反,Java 12为我们提供了原始/多行字符串。 那也很好

原始字符串

考虑例如使用正则表达式搜索句点。 正则表达式为\. 因为您必须在正则表达式中转义一个句号。 因此在Java中,它是Pattern.compile("\\.") 。 要匹配反斜杠,它是Pattern.compile("\\\\") 。 这会变得很混乱。

实际上,它是如此令人困惑,以至于JEP 326的作者弄错了它,或者也许具有微妙的幽默感。 作者的示例是Pattern.compile("\\\"")以匹配" 。 当然,您不需要在正则表达式中进行转义,因此Pattern.compile("\"")可以正常工作,这证实了所有转义都是一团糟。

解决方法很简单。 将字符串括在反引号`...` 。 反引号内的所有内容都无需逃脱: Pattern.compile(`\.`)

但是,如果字符串包含反引号怎么办?

在Scala和Kotlin中,使用"""分隔符,但这引出了问题。如果字符串包含"""怎么办?

这是Java设计师提出我以前从未见过的一个聪明的主意。 您可以使用任意数量的反引号来开始一个原始字符串,然后使用相同数量的反引号来结束它。 例如,如果您知道您的字符串中没有五个连续的反引号,请执行以下操作:

String s = `````. . .
. . .
. . .
. . .`````; // Five golden backticks :-)

字符串中的所有内容均照原样进行。 如果它是一些HTML或SQL或您在其他地方开发的任何东西,则将其粘贴。

实际上,“原样”是一个例外。 即使源文件使用Windows风格的\r\n行尾,所有行尾都被标准化为\n

美中不足的苍蝇

Stephen Colebourne指出,两个反引号可能会与空字符串混淆。 如果你有类似的东西

s = ``;
t = ``;

则不会将st设置为空字符串,而是将s设置为字符串";\nt = "

那里有个很好的谜题。

原始字符串不能以反引号开头或结尾。 例如,假设您要将以下Markdown片段放入Java字符串中:

<

pre>“`警报(“ Hello,World!”)


You obviously can&#39;t add backticks at the start, so the best thing you can do is add a space or newline before the ```. And the same holds for the end. Java requires that the ending delimiters exactly match the start. (In contrast, in Scala, you can write """Hello, "World"""", and the compiler figures out that one of the terminal quotation marks belongs to the string.)So, you can write:

String markdown = `````

警报(“ Hello,World!”)““”`.strip();

strip调用将删除\n在开头和结尾。 或者,也可以将换行符留在原处,如果它们无关紧要。

( strip方法是Java 11的新功能。它与trim相似,但是它去除了开头和结尾的Unicode空白,而trim删除了≤32的字符,这已经不一样了。这些天,您应该使用strip ,而不是trim 。)

IDE支持

激活JDK 12的实验功能时,IntelliJ 2018.3可以将带有反斜杠的字符串转换为原始字符串。(有关详细信息,请参阅此博客文章。)

五弦
我尝试转换老式的多行字符串:

private static final String authorPublisherQuery = "SELECT Books.Price, Books.Title\n"+ " FROM Books, BooksAuthors, Authors, Publishers\n"+ " WHERE Authors.Author_Id = BooksAuthors.Author_Id AND BooksAuthors.ISBN = Books.ISBN\n"+ " AND Books.Publisher_Id = Publishers.Publisher_Id AND Authors.Name = ?\n"+ " AND Publishers.Name = ?\n";

那是行不通的,但是没有理由为什么将来不会。

压痕管理

我更喜欢在最左边的列上排列多行字符串。 例如,

public static void main(String[] args) {String myNameInABox = `
+-----+
| Cay |
+-----+`.strip(); System.out.print(myNameInABox);}

它使多行字符串从Java代码中脱颖而出。 它为您放入原始字符串中的所有内容提供了足够的水平空间。

但是,很多人似乎更喜欢将多行字符串的内容与Java代码对齐的样式:

...String myNameInABox = `+-----+| Cay |+-----+`.align();System.out.print(myNameInABox);

align方法(在Java 12中定义)删除空格的公共前缀以及空白行的开头和结尾。

这种方法存在风险。 如果混合使用制表符和空格,则每个制表符都计为一个空格。 在您的IDE中,有些东西看起来与您对齐,但与align方法不一致。 当然,您的IDE可能会警告您这种情况。 IntelliJ 2018.3当前不这样做。

没有走的路

关于新功能的许多讨论都在“ Amber Spec”邮件列表中进行,您可以在http://mail.openjdk.java.net/pipermail/amber-spec-observers/上进行观察,因此您可以查看具有哪些替代方法被考虑。

关于是否应该自动删除缩进进行了激烈的讨论。 可以预见,这最终没有被采纳。

原始字符串中的Unicode转义怎么办? \u0060应该是反引号吗? 理智盛行,决定“原始意味着原始”。

是否应该将两个反引号定为非法,因为``可能与空字符串混淆? 不可以,只有一个简单的规则,即“任何数量的反引号”。

在开始反引号之后换行怎么样? 关于是否应该将其剥离存在一些问题。 我仍然感到遗憾的是没有对此问题给予更多关注。 将换行符包含在开头的定界符中将解决两个问题:初始反引号和最左侧列的对齐。

我胆怯地问,为什么关闭分隔符不能“至少与打开分隔符一样多的反引号”(类似于Scala),以便原始字符串可以以反引号结尾。 不幸的是,我没有回应。

令人惊讶的是,像这样的概念上简单的功能有多少细节。 撇开小调,这是一个非常受欢迎的礼物,正好赶上假期。

翻译自: https://www.javacodegeeks.com/2018/12/five-golden-backticks.html

五金手册



推荐阅读
author-avatar
上床后悔_155
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有