У меня есть этот обычный тернарный оператор, но мне нравится, когда он выполняет больше одной операции, если ложь
например :

def xxStr = x.x.1.1
    def ver = 0
    xxStr = (xxStr.contains('foo')) ? xxStr.replace('-foo','').tokenize('.') : xxStr.tokenize('.') && ver = xxStr.pop()

Конечно это не работает как xxStr.tokenize('.') && ver = xxStr.pop()
это не законно, но есть ли какой-нибудь элегантный способ сделать это?

0
user63898 10 Фев 2020 в 12:13

3 ответа

Лучший ответ

Вам понадобится блок кода, который можно выполнить сразу.

Одним из вариантов (очевидно) является вызов функции, которая будет выполнять все операции:

def func() {
  println("no")
  println("definitely not")
}
(10 > 20) ? println ("yes") : func()

Другой вариант - использовать закрытие:

​(10 > 20) ? println("yes") :  {​​​​​​​println("no"); println ("definitely not")​​​​​​​​​​​​}.call()

Обе версии печатают:

no
definitely not
0
Mark Bramnik 10 Фев 2020 в 09:28

Другой вариант - использовать with как в:

xxStr = xxStr.contains('foo') ? xxStr.replace('-foo','').tokenize('.') : xxStr.tokenize('.').with { pop() }
2
tim_yates 10 Фев 2020 в 09:54

Тернарный оператор присваивает значение переменной, поэтому здесь нельзя вызвать выражение присваивания. Но есть и другие проблемы с кодом, который вы представили. Например:

xxStr.tokenize('.') && ver = xxStr.pop()

Ожидать, что xxStr после вызова xxStr.tokenize('.') является списком, является заблуждением. xxStr в этом выражении остается String, поэтому вызов pop для него выдает MissingMethodException.

Принуждение вашего кода быть однострочным не означает, что вы используете элегантное решение. В этом случае я бы сказал, что все наоборот. Кроме того, вы используете def в динамическом контексте (вы меняете тип с String на List). Это не запрещено, но в большинстве случаев только вносит путаницу. Это затрудняет понимание вашего кода и его рассуждения.

Я настоятельно рекомендую разделить код на две отдельные секции: одну, отвечающую за токенизацию строки в массив, и вторую, которая отвечает за вывод версии. Это делает ваш код более понятным и простым для понимания. Если бы в Groovy было встроенное простое для чтения решение, вы можете использовать его. Но добавление этого ненужного уровня абстракции к такому простому варианту использования имеет очень мало смысла.

0
Szymon Stepniak 10 Фев 2020 в 09:26