Что не так с многострочными строками Groovy?


106

Скрипты Groovy вызывают ошибку:

def a = "test"
  + "test"
  + "test"

Ошибка:

No signature of method: java.lang.String.positive() is 
applicable for argument types: () values: []

Пока этот скрипт работает нормально:

def a = new String(
  "test"
  + "test"
  + "test"
)

Зачем?


5
Если это поможет кому-то другому, вы можете получить ту же ошибку с кодом вроде def a = b + + "/" + c. В этом случае, очевидно, проблема заключается в двух символах +.
Джефф Хакворт,

Ответы:


237

Поскольку у Groovy нет маркера EOL (например, ; ), он запутается, если вы поместите оператор в следующую строку

Вместо этого это будет работать:

def a = "test" +
  "test" +
  "test"

поскольку синтаксический анализатор Groovy знает, что ожидать чего-то в следующей строке

Groovy рассматривает ваш оригинал defкак три отдельных утверждения. Первые правопреемников testк a, второй два раза , чтобы сделать "test"положительный (и это, где это не получится )

С помощью new Stringметода конструктора синтаксический анализатор Groovy все еще находится в конструкторе (поскольку фигурная скобка еще не закрыта), поэтому он может логически объединить три строки в один оператор.

Для настоящих многострочных строк вы также можете использовать тройную кавычку:

def a = """test
test
test"""

Создадим строку с тестом на трех строках

Кроме того, вы можете сделать его более аккуратным:

def a = """test
          |test
          |test""".stripMargin()

stripMarginметод будет обрезать левый (до и включая |символ) из каждой строки


6
Или просто используйте stripIndent () вместо stripMargin().
sschuberth

Да, и опускайте |символы в дополнительных строках
tim_yates

4
Вы можете использовать двойные кавычки внутри """строк
tim_yates

3
Правильно, я отредактировал ответ, чтобы показать, как вам нужно немного переформатировать код, чтобы он заработал stripIndent().
sschuberth

2
Потому что а) я уже опубликовал его как комментарий, и б) он не сильно отличается от этого ответа.
sschuberth

18

Аналогично stripMargin(), вы также можете использовать stripIndent () как

def a = """\
        test
        test
        test""".stripIndent()

Из-за

Строка с наименьшим количеством ведущих пробелов определяет число, которое нужно удалить.

вам также необходимо сделать отступ для первого «теста» и не помещать его сразу после начального """(это \гарантирует, что многострочная строка не начинается с новой строки).


2
что за \ для?
Джо Филлипс

4
Я улучшил свое последнее предложение, чтобы лучше его объяснить.
sschuberth

17

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

def a = ("test"
  + "test"
  + "test")

Второй вариант - использовать обратную косую черту \в конце каждой строки:

def a = "test" \
  + "test" \
  + "test"

FWIW, это идентично тому, как работают многострочные операторы Python.


Второе - это также то, как работают многострочные операторы VBA: D (Только с подчеркиванием вместо обратной косой черты, потому что VBA.)
Чарльз Вуд

Второй вариант не удался для меня в файле Jenkins. Первый вариант сработал.
SilverJan

Nitpick: многострочная строка Python не требует оператора конкатенации при использовании скобок, поэтому это не совсем то же самое.
Big McLargeHuge
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.