Що не так у багаторядковому рядку Groovy?


105

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. У цьому випадку два + символи, очевидно, є проблемою.
Джефф Хакворт

Відповіді:


236

Оскільки в groovy немає маркера EOL (наприклад ;), він заплутається, якщо поставити оператора на наступний рядок

Це буде працювати замість цього:

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

як Groovy аналізатор знає чекати чогось у наступному рядку

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

За допомогою new Stringконструкторного методу аналізатор Groovy все ще знаходиться в конструкторі (оскільки дужка ще не закрилася), тому він може логічно об'єднати три рядки разом в одне твердження

Для справжніх рядкових рядків ви також можете використовувати потрійну цитату:

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

Створимо String з тестом у трьох рядках

Крім того, ви можете зробити його акуратніше:

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()

Тому що

Рядок з найменшою кількістю провідних пробілів визначає число, яке потрібно видалити.

Вам також потрібно відступити перший "тест", а не ставити його безпосередньо після inital """( \гарантує, що багаторядковий рядок не починається з нового рядка).


2
для чого \
Джо Філіпс

4
Я вдосконалив своє останнє речення, щоб краще пояснити його.
sschuberth

17

Ви можете сказати Groovy, що оператор повинен оцінювати минулий рядок, що закінчується, додавши пару дужок ( ... )

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

Другий варіант - використовувати зворотний проріз \, в кінці кожного рядка:

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

FWIW, це ідентично тому, як працюють багаторядкові оператори Python.


Другий - також про те, як працюють багаторядкові висловлювання VBA: D (Тільки з підкресленнями замість відхилень, тому що VBA.)
Чарльз Вуд

Другий варіант для мене не вдався в Jenkinsfile. Перший варіант спрацював.
SilverJan

Nitpick: багаторядковий рядок Python не вимагає оператора конкатенації при використанні паронів, тому це не зовсім те саме.
Big McLargeHuge
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.