Hi all,
In most of cases, we just use GString as an enhanced String, but
currently GString is not implemented eager so it has some weird features,
which will confuse users. Let's look at some examples[1] from Jochen:
* the referenced variables are bound eager
* toString on GString evaluates the GString, this includes toString for the
values
```
def x = 1
def gstring = "$x"
assert gstring == "1"
x = 2
assert gstring == "1"
```
```
class X {
int i = 0
String toString(){Integer.toString(i++)}
}
def x = new X()
def gstring = "$x"
assert gstring == "0"
assert gstring == "1" // the content of gstring changed...
```
If we implement GString eager and treated as normal String(not expose
GString API), the content of GString will not change once it is evaluated.
We can get the following benefits:
1) Users will not be confused because of some weird feature;
2) Better compatibility between dynamic and static compilation, SEE
GROOVY-6668[1];
3) The performance will be improved to some extent because GString will not
be evaluated again and again even if its content is not changed;
The proposal is a breaking change, so I propose it is targeted to
groovy 3.0.0 if accepted.
P.S. some issues like GROOVY-6668 are raised by users again and again, that
is say, many users are confused by current implementation, i.e. GString can
not be treated as normal String in STC. In the static compilation mode:
```
@groovy.transform.CompileStatic
class Test {
static void main(String[] args) {
def m = ['a':1, 'b':2]
def k = 'a'
assert 1 == m[k]
assert 1 == m["$k" as String]
assert 1 == m["$k"] // fails, gets null, which is not equal to 1
}
}
```
Cheers,
Daniel.Sun
[1] https://github.com/apache/groovy/pull/708
-----
Daniel Sun
Apache Groovy committer
Blog: http://blog.sunlan.me
Twitter: @daniel_sun
--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html