意图在文本块中的处理方式(Java 13) [英] How the intents processed in a Text block(Java 13)

查看:78
本文介绍了意图在文本块中的处理方式(Java 13)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚尝试了Java 13中的新文本块功能,但遇到了一个小问题.

I just tried the new text block feature in Java 13 and encountered a small issue.

我已阅读 Jaxcenter的这篇文章.

用三引号引起来会影响格式.

The closing triple quotation marks will affect the format.

String query = """
            select firstName,
            lastName,
            email
            from User
            where id= ?
        """;

System.out.println("SQL or JPL like query string :\n" + query);

上述格式效果很好.为了与结束定界符(")对齐,多行字符串在每行之前保留空格.

This above format works well. To align with the the closing delimiter ("""), the multiline string left spaces before every lines.

但是当我尝试比较以下两个文本块字符串时,它们在输出控制台中的格式相同,但是即使在stripIntent之后,它们也不相等.

But when I tried to compare the following two text block string, they are same format in the output console, but they are not equals, even after stripIntent.

String hello = """
    Hello,
    Java 13
    """;

String hello2 = """
    Hello,
    Java 13
""";

System.out.println("Hello1:\n" + hello);
System.out.println("Hello2:\n" + hello);

System.out.println("hello is equals hello2:" + hello.equals(hello2));

System.out.println("hello is equals hello2 after stripIndent():" + hello.stripIndent().equals(hello2.stripIndent()));

输出控制台类似于:

hello is equals hello2:false
hello is equals hello2 after stripIndent():false

我不确定哪里出错了,或者这是文本块设计的目的吗?

I am not sure where is wrong, or this is a text block design purpose?

更新:只需打印hello2 stripIntent,

Update: Just print hello2 stripIntent,

System.out.println("hello2 after stripIntent():\n" + hello2.stripIndent());

stripIntent会按预期删除每行前面的空格.

The whitespaces before every lines are NOT removed by stripIntent as expected.

已更新:在阅读了相关的Java文档之后,我认为在编译文本块之后,它应该已经删除了该块中各行的左侧意图. stripIntent用于文本块的目的是什么?我知道在普通字符串上使用它很容易理解.

Updated: After read the related java doc, I think after the text block is compiled, it should has stripped the left intents of the lines in the block. What is the purpose of stripIntent for text block? I know it is easy to understand when use it on a normal string.

完整的代码是推荐答案

有一个 偶然空格的概念.

There is a concept of incidental white space.

JEP 355:文本块(预览)

编译时处理

JEP 355: Text Blocks (Preview)

Compile-time processing

文本块是String类型的常量表达式,就像字符串文字一样.但是,与字符串文字不同,Java编译器通过三个不同的步骤来处理文本块的内容:

A text block is a constant expression of type String, just like a string literal. However, unlike a string literal, the content of a text block is processed by the Java compiler in three distinct steps:

  • 内容中的行终止符转换为LF(\ u000A).这种翻译的目的是在跨平台移动Java源代码时遵循最小惊喜的原则.

  • Line terminators in the content are translated to LF (\u000A). The purpose of this translation is to follow the principle of least surprise when moving Java source code across platforms.

围绕内容的偶然空白被删除,以匹配Java源代码的缩进.

转义序列被解释.作为最后一步执行解释,意味着开发人员可以编写转义序列,例如\ n,而无需通过较早的步骤进行修改或删除.

Escape sequences in the content are interpreted. Performing interpretation as the final step means developers can write escape sequences such as \n without them being modified or deleted by earlier steps.

...

偶然的空格

这里是HTML示例,该示例使用点来可视化 为缩进添加了开发人员:

Here is the HTML example using dots to visualize the spaces that the developer added for indentation:

String html = """
..............<html>
..............    <body>
..............        <p>Hello, world</p>
..............    </body>
..............</html>
..............""";

由于通常将开头定界符放置在与语句或 消耗文本块的表达式,没有真正的 每行开始有14个可视化空间这一事实很重要. 在内容中包含这些空格将表示文本块 表示与串联表示的字符串不同的字符串 字符串文字.这会伤害迁移,并且会成为反复出现的来源 出乎意料的是:绝大多数情况下,开发人员不会 想要字符串中的那些空格.另外,结束定界符是 通常定位为与内容保持一致,这进一步表明 14个可视化空间微不足道.
...
因此,对文本块内容的适当解释是,将每行开头和结尾处的附带空白与必要的空白区分开. Java编译器通过删除附带的空白来处理内容产生开发人员想要的东西.

Since the opening delimiter is generally positioned to appear on the same line as the statement or expression which consumes the text block, there is no real significance to the fact that 14 visualized spaces start each line. Including those spaces in the content would mean the text block denotes a string different from the one denoted by the concatenated string literals. This would hurt migration, and be a recurring source of surprise: it is overwhelmingly likely that the developer does not want those spaces in the string. Also, the closing delimiter is generally positioned to align with the content, which further suggests that the 14 visualized spaces are insignificant.
...
Accordingly, an appropriate interpretation for the content of a text block is to differentiate incidental white space at the start and end of each line, from essential white space. The Java compiler processes the content by removing incidental white space to yield what the developer intended.

您的假设

    Hello,
    Java 13
<empty line>

等于

....Hello,
....Java 13
<empty line>

不准确,因为它们是 必需空格,并且编译器或

is inaccurate since those are essential white spaces and they will not be removed by either the compiler or String#stripIndent.

为了清楚起见,让我们继续将偶然的空白表示为点.

To make it clear, let's keep representing an incidental white space as a dot.

String hello = """
....Hello,
....Java 13
....""";

String hello2 = """
    Hello,
    Java 13
""";

让我们打印它们.

Hello,
Java 13
<empty line>

    Hello,
    Java 13
<empty line>

让我们打电话 String#stripIndent 并打印结果.

Let's call String#stripIndent on both and print the results.

Hello,
Java 13
<empty line>

    Hello,
    Java 13
<empty line>

要了解为什么什么都没有改变,我们需要查看文档.

To understand why nothing has changed, we need to look into the documentation.

String#stripIndent

Returns a string whose value is this string, with incidental white space removed from the beginning and end of every line.

然后,最小压痕(分钟)确定如下.对于每个非空白行(由

Then, the minimum indentation (min) is determined as follows. For each non-blank line (as defined by isBlank()), the leading white space characters are counted. The leading white space characters on the last line are also counted even if blank. The min value is the smallest of these counts.

对于每条非空白行,将删除最小的前导空白字符,并删除所有尾随的空白字符.空行将替换为空字符串.

For each non-blank line, min leading white space characters are removed, and any trailing white space characters are removed. Blank lines are replaced with the empty string.

对于两个String,最小缩进均为0.

For both Strings, the minimum indentation is 0.

Hello,          // 0
Java 13         // 0    min(0, 0, 0) = 0 
<empty line>    // 0

    Hello,      // 4
    Java 13     // 4    min(4, 4, 0) = 0
<empty line>    // 0

String#stripIndent gives developers access to a Java version of the re-indentation algorithm used by the compiler.

JEP 355

重新缩进算法在Java语言规范中是规范性的.开发人员可以通过新实例方法String::stripIndent来访问它.

JEP 355

The re-indentation algorithm will be normative in The Java Language Specification. Developers will have access to it via String::stripIndent, a new instance method.

由文本块表示的字符串不是内容中字符的文字序列.而是由文本块表示的字符串是对内容按以下顺序进行转换的结果:

The string represented by a text block is not the literal sequence of characters in the content. Instead, the string represented by a text block is the result of applying the following transformations to the content, in order:

  1. 行终止符被规范化为ASCII LF字符(...)

  1. Line terminators are normalized to the ASCII LF character (...)

删除偶然的空格,就像在内容中的字符上执行String::stripIndent 一样.

Incidental white space is removed, as if by execution of String::stripIndent on the characters in the content.

转义序列的解释方式与字符串文字相同.

Escape sequences are interpreted, as in a string literal.

这篇关于意图在文本块中的处理方式(Java 13)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆