Groovy Поведение GStringImpl и String

Недавно я читал о поведении GStringImpl и String при использовании в коллекциях в Groovy.

Я понимаю, что причина этого оценивается как ложная...

"${'test'}".equals("test") == false

происходит из-за требования симметрии контракта .equals(), однако мне было интересно, была ли причина, по которой GStringImpl не мог быть просто сразу оценен как String. Поэтому, когда я делаю что-то вроде этого...

"${'someString'}"

Я не получаю GStringImpl, я просто возвращаю простую String Java, которую я могу немедленно использовать, например, в качестве ключа на карте.

Я знаю, что есть некоторые обходные пути, такие как

String s = "${'someString'}"

однако такие вещи немного неудобны, и GStringImpl между GStringImpl и String кажется, является большой "ошибкой" для новичков в Groovy.

Ответ 1

GStrings не оцениваются непосредственно в String по ряду причин, в основном связанных с отложенной оценкой (что очень хорошо для регистрации) и шаблонизацией. В Strings и GString вы можете найти хорошее объяснение:

GString может включать в себя ленивую оценку, поэтому до тех пор, пока метод toString() не будет вызван, вычисляется GString. Эта ленивая оценка полезна для таких вещей, как ведение журнала, так как она позволяет вычислять строку, вызывать toString() для значений и объединять различные строки, если вообще делать, лениво.

GString очень удобен, когда вы не хотите использовать шаблонизатор или когда вам действительно нужна полная ленивая оценка GStrings. Когда какая-то переменная встроена в GString, для этой строчки вызывается toString(), чтобы получить строковое представление, и она вставляется в окончательную строку.

Следовательно:

GString и String - это два разных класса, и, следовательно, использование объектов GString в качестве ключей для объектов Map или сравнений с объектами GString может привести к неожиданным результатам в сочетании с объектами String, поскольку GString и String не будут иметь одинаковый hashCode и не будут быть равным Нет автоматического приведения между этими двумя типами для сравнения или ключей карты, поэтому иногда необходимо явно вызывать toString() для объектов GString.

Неожиданное преобразование в String может привести к проблемам, когда код ожидает GString, как для методов в классах groovy.sql.