I've recently been reading about the behavior of GStringImpl
s vs String
s when used in collections in Groovy.
I understand that the reason this evaluates to false...
"${'test'}".equals("test") == false
is due to the symmetry requirement of the .equals()
contract, however I was wondering if there was a reason the GStringImpl
couldn't just be evaluated to a String
immediately. So when I do something like this...
"${'someString'}"
I don't get a GStringImpl
, I just get a plain Java String
back, which I can immediately use as the key in a map, for example.
I know there are some workarounds, like
String s = "${'someString'}"
however stuff like this is a bit inconvenient, and the mix-up between GStringImpl
and String
seems to be a big 'gotcha' for Groovy newbies.
GStrings are not evaluated inmediately to String because of some reasons, mainly related to lazy evaluation (which is quite good for logging) and templating. In Strings and GString you can find a good explanation:
GString
can involve lazy evaluation so it's not until the toString() method is invoked that the GString is evaluated. This lazy evaluation is useful for things like logging as it allows the calculation of the string, the calls to toString() on the values, and the concatenation of the different strings to be done lazily if at all.GString is pretty handy when you don't want to use a template engine, or when you really want full lazy evaluation of GStrings. When some variable embedded in a GString, the toString() is called on that variable to get a string representation, and it's inserted into the final string.
Therefore:
GString and String are two distinct classes, and hence use of GString objects as keys for Map objects or comparisons involving GString objects, can produce unexpected results when combined with String objects since a GString and a String won't have the same hashCode nor will they be equal. There is no automatic coercion between the two types for comparisons or map keys, so it's sometimes necessary to explicitly invoke toString() on GString objects.
Unexpected conversion to String can lead to problems when code is expecting a GString, as for methods in groovy.sql classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With