Текстовые блоки Java: сочетание табуляции и пробелов в префиксах отступа
В Java 15 появилась функция текстовых блоков (без предварительного просмотра). Он позволяет определять многострочные строковые литералы без нарушения отступов кода, удаляя общий префикс пробела из строк. Алгоритм описан в JEP 378.
Но как именно определяется "префикс общего пробела" в случае, если строки имеют отступ с использованием сочетания табуляции и пробелов?
Например, каким будет строковое значение в следующем случае (·
означает пространство,
→
означает символ табуляции):
→ → ···· Строка text = """ → → ····→ строка1 → ········→ строка2 → ····→ → """;
Простой тест с OpenJDK показывает, что строка результата:
линия 1 ··→ строка2
Таким образом, похоже, что Javac просто считает символы пробелов, включая пробелы и табуляции, и использует счетчик, одинаково обрабатывая пробелы (0x20) и табуляции (0x09). Это ожидаемое поведение?
Примечание: это не чисто теоретический вопрос; это имеет практическое значение для проекта со смешанными отступами пробелов / табуляций и большой кодовой базой.
1 ответ
Я нашел ответ, которым хочу поделиться.
Компилятор Java действительно одинаково обрабатывает пробелы, табуляции и все другие пробельные символы.
Таким образом, одинаковое количество (любых) пробелов удаляется из каждой строки.
Детали:
javac
токенизатор использует String.stripIndent()
метод, который имеет следующее примечание по реализации:
Этот метод обрабатывает все символы пробела как имеющие одинаковую ширину. Пока отступ в каждой строке последовательно состоит из одних и тех же последовательностей символов, результат будет таким, как описано выше.