Строка с тройной кавычкой внутри строки с тройной кавычкой - PullRequest
0 голосов
/ 09 ноября 2018

Я использую строку с тройной кавычкой внутри строки с тройной кавычкой:

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 голосов
/ 09 ноября 2018

Странность с 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 () : String Обнаруживает общий минимальный отступ для всех входные строки, удаляет его из каждой строки, а также удаляет первый и последние строки, если они не заполнены ( заметьте разницу между пустыми и пусто ). Обратите внимание, что пустые строки не влияют на обнаруженный уровень отступа. В случае если есть непустые строки без начальных пробельных символов (без отступа вообще), то общий отступ равен 0, и, следовательно, эта функция не меняет отступ.

Не сохраняет исходные окончания строк.

Следующее утверждение: «заметьте разницу пустым против пустого», может содержать ключ к загадке, хотя не совсем понятно, что они подразумевают под этим; определенно странное поведение (может быть, ошибка?).

0 голосов
/ 09 ноября 2018

На самом деле проблема не в 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 начинает работать с ним, сначалаон пытается найти общий отступ, но не может его найти, так как одна из строк (OLOLO) не имеет отступа.Так что ничего не поделаешь.Вот почему пробел до new added text остается).

Вы можете увидеть это, если поставить точку останова в реализации trimIndent, чтобы увидеть, что является получателем (то есть какое значение secondStr находится передtrimIndent начинает свою работу).

Так что ваше решение верное.Добавьте символ трубы и используйте trimMargin.Канал означает, что перед добавленным текстом нет 4 пробелов, поэтому он корректно все обрезает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...