Groovy String评估运行时

Xel*_*ian 2 string groovy closures gstring

嗨,我有一个填充运行时的字符串值,我想用它来构造另一个字符串.

static value= ''
static construct = "${-> value - '/'}"
Run Code Online (Sandbox Code Playgroud)

所以,当我 ="/www.stackoverflow.com"时,构造等于"www.stackoverflow.com "

但是当我这样做的时候

static value= ''
static construct = {-> value - '/'}
Run Code Online (Sandbox Code Playgroud)

construct等于一些关闭名称.我想知道这是什么目的?为什么使用闭包,GString一切正常?为什么只使用闭合没有任何反应?

已编辑: 此方法调用的值已更改.

def someCoplmexMethod(){
   value="/www.stackoverflow.com"
}
Run Code Online (Sandbox Code Playgroud)

bla*_*rag 10

简而言之,"${-> value - '/'}"是一个完全懒惰的评估GString的值.

首先澄清一些事情...... "value"是一个值为"value"的String."$value"是一个GString,它的值等于String的值.因此,如果值为"lol.com",那么这也是GString等于的值.

需要注意的重要事项是这里有两件事,GString的值是懒惰的,但是用于此的对象不是.因此,如果"$value"value是一个带有toString()方法的类,每次都会返回一个不同的String,那么GString的toString()每次都会有所不同.当然,String对象不是这种情况.所以如果你有例如代码

def value=1
def gstring="$value"
value=2
assert gstring=="1"
Run Code Online (Sandbox Code Playgroud)

然后gstring仍然是"2".

{->value}现在是一个开放的块,它将返回值.评估是懒惰的,因此每次都是如此.所以

def value=1
def closure={->value}
def a=closure()
value=2
def b=closure()
assert a==1
assert b==2
Run Code Online (Sandbox Code Playgroud)

然后a将得到值1和b得到值2.类似方法调用的表达式closure()将调用open块.

最后"${-> value - '/'}"将被视为包含开放块的GString.每次像往常一样调用toString()方法时,GString将评估open块,但这次这将导致open块的调用,从而再次计算值本身.结果是:

def value=1
def gstring="${-> value}"
value=2
assert gstring=="2"
Run Code Online (Sandbox Code Playgroud)

如果您将示例与简单的GString版本进行比较,那么您将看到结果已更改.一个更复杂的例子:

def i=1
def gstring="${-> i++}"
assert gstring=="1"
assert i==2
assert gstring=="2"
assert i==3
assert gstring=="3"
assert i==4
Run Code Online (Sandbox Code Playgroud)

如您所见,由于open块,每次计算时,gstring的toString()值都会发生变化.