Как избавиться от "null" при конкретизации строки в groovy?

У меня есть класс

class A{
    String name
    String address
}

def a = new A()
a.address = "some address"    
println "${a.name} ${a.address}"  => "null some address"

Здесь a.name имеет значение null, поэтому напечатанная строка будет содержать "null", однако я надеюсь, что результат будет "some address", который игнорирует нулевое значение.

Я знаю, что при печати можно использовать println "${a.name ?: ''} ${a.address ?: ''}", есть ли более простое решение?

Ответ 1

Вы можете переопределить метод toString для объекта Groovy null, чтобы вернуть пустую строку вместо null.

def a = [a:null, b:'foobar']
println "${a.a} ${a.b}"
org.codehaus.groovy.runtime.NullObject.metaClass.toString = {return ''}
println "${a.a} ${a.b}"

Это напечатает:

null foobar
 foobar

Если вы хотите временно переопределить toString, добавьте следующее после последнего print..., чтобы изменить его:

org.codehaus.groovy.runtime.NullObject.metaClass.toString = {return 'null'}

Вы также можете изменить поведение null toString с помощью Groovy Category [1] [ 2]. Например:

@Category(org.codehaus.groovy.runtime.NullObject) class MyNullObjectCategory {def toString() {''}}
use (MyNullObjectCategory) {
    println "${a.a} ${a.b}"
}

Ответ 2

Вы можете реализовать метод toString в своем классе:

class A{
  String name
  String address
  String toString() {
    "${name ?: ''} ${address ?: ''}".trim()
  }
}

то do

def a = new A( address:'some address' )
println a

Чтобы распечатать some address, но это все еще использовало оператор Элвиса, как и в вашем вопросе...

Не уверен, что намного проще вы можете сделать...

Ответ 3

Не уверен, что проще, но:

[a.name, a.address].findAll().join(' ')

Конечно, вы можете комбинировать его с предложением Tim toString .

Обратите внимание, что если какое-либо из значений может быть "ложным" (например, 0), оно будет отфильтровывать его. Вы можете исправить это:

[a.name, a.address].findAll {it != null}.join(' ')