带三引号的字符串位于带三引号的字符串内部

时间:2018-11-09 16:14:23

标签: string kotlin

我在带三引号的字符串中使用带三引号的字符串:

fun main(args: Array<String>) {    
    val firstStr = """

    OLOLO
    """.trimIndent()

    val secondStr = """
    $firstStr
    new added text
    """.trimIndent()

    println("The firstStr is $firstStr")
    println("The secondStr is $secondStr")
}

我得到以下输出:

The firstStr is 
OLOLO
The secondStr is     
OLOLO
    new added text

我很困惑为什么缩进保留在最后一行(" new added text")...因为我期望trimIndent()方法必须修剪所有缩进(如文档注释所说的那样

  

检测所有输入行的公共最小缩进,将其删除   从每一行中删除第一行和最后一行   为空白(注意差异为空白还是空白)。

同时,我可以使用trimMargin()和默认参数(“ |”)来削减此缩进:

fun main(args: Array<String>) {    
    val firstStr = """

    OLOLO
    """.trimIndent()

    val secondStr = """
    $firstStr
    |new added text
    """.trimMargin()

    println("The firstStr is $firstStr")
    println("The secondStr is $secondStr")
}

在这种情况下,我得到以下输出:

The firstStr is 
OLOLO
The secondStr is     
OLOLO
new added text

但是我不明白为什么trimIndent()不修剪该缩进...

2 个答案:

答案 0 :(得分:3)

trimIdent()的怪异似乎是由于开头有空行引起的。尽管前导空白行似乎毫无疑问地使所有内容显得毫无用处,但它对于前导制表符和空格在整个过程中的一致性还是有些挑剔。因此,您可以在\n中包含换行符(println)作为解决方法。

fun main(args: Array<String>) {    

    val firstStr =
        """
            OLOLO
        """.trimIndent()

    val secondStr = 
        """
            $firstStr
            new added text
        """.trimIndent()

    println("The firstStr is \n$firstStr")
    println("The secondStr is \n$secondStr")

}

输出

The firstStr is
OLOLO
The secondStr is
OLOLO
new added text
  

String.trimIndent():字符串检测所有字符的通用最小缩进   输入行,将其从每行中删除,也删除第一行   以及最后一行(如果为空白)(注意差异为空白vs   空)。请注意,空行不会影响检测到的缩进级别。如果存在不带前导空格字符(根本没有缩进)的非空白行,则公共缩进为0,因此此功能不会更改缩进。

     

不保留原始行结尾。

以下语句:“注意差异为空白还是为空”,这可能是谜语的关键,尽管目前尚不清楚它们的含义。绝对是奇怪的行为(也许是错误?)。

答案 1 :(得分:2)

该问题实际上不在trimIndent中。这与原始字符串文字包含参数时的工作方式有关。您从以下开始:

{
    val firstStr = """

    OLOLO
    """.trimIndent()
}

其结果是firstStr具有以下值:

"
OLOLO"

然后使用以下代码将其注入secondStr中:

{
    val secondStr = """
    $firstStr
    new added text
    """.trimIndent()
}

现在想象一下,您实际上是在此键入而不是使用参数值。您可以这样操作(我将用下划线替换一些空格以澄清某些内容):

{
    val secondStr = """

____OLOLO
    new added text
    """.trimIndent()
}

一切正常。但是,当将值注入到原始字符串文字中时,实际上并不会发生这种情况,因为您不知道要在上面加下划线的地方放置空格。就系统而言,您只是在告诉它先输入回车符,然后再输入OLOLO。因此,实际上发生的是生成的值(在之前 trimIndent被调用之前)是

{
    val secondStr = """

OLOLO
    new added text
    """.trimIndent()
}

然后,在trimIndent开始使用它时,它要做的第一件事就是尝试寻找一个通用的缩进,但是找不到其中一个,如其中一行({{1 })不缩进。因此,它无能为力。这就是OLOLO之前的空白保留的原因。

如果您在new added text的实现中放置一个断点以查看接收者是什么(即trimIndentsecondStr开始工作之前的值是多少),您可以看到此内容。 / p>

因此您的解决方案是正确的。添加一个竖线字符并使用trimIndent。竖线表示添加的文字前没有4个前导空格,这就是为什么它会正确修剪所有文字。