声明一个带有空映射的变量,然后为它分配一个不同的对象是一种有效的模式吗?

Is declaring a variable with an empty map, and then assigning a different object to it an efficient pattern?

我们正在开发一个 Grails 项目,我是 Grails/Groovy 新手,我看到一种模式,我们在控制器中将变量定义为空映射,然后在服务方法中也定义另一个空地图,并用数据库中的 key/value 对填充它。

我的观点是这种模式很浪费。我们正在将一个空映射分配给控制器变量,只是为了在服务中创建另一个映射,然后将服务映射分配给控制器变量,从而孤立在控制器中创建的空映射,并将其释放以进行垃圾回收。

一位同事争辩说,来自服务映射的数据最终会出现在控制器映射中,这样在控制器中创建的原始映射就被使用了,因此宣称它没有浪费。

到底发生了什么?创建的第一个控制器映射只是为了进行垃圾收集,还是以某种方式填充了服务映射中的数据?

控制器方法:

getMap() {
    ....
    def output = [:]
    output = someService.getHashMap()
    ...
}

服务方式:

getHashMap() {
    ...
    def output = [:]
    output = [key0: 'value0', key1: 'value1', key2: 'value2']
}

它正在设置一个从未用于变量的对象引用,然后设置另一个对不同地图实例(可能在服务内部创建)的引用。垃圾收集器将删除第一个空映射,这不是一个大的性能问题,但很容易避免。 要添加地图的内容,您需要使用 putAll 或左移运算符 <<.

没有充分的理由做这样的事情...

def output = [:]
output = [key0: 'value0', key1: 'value1', key2: 'value2']

也许这有助于弄清楚发生了什么。下面等价于上面的代码...

def output = new LinkedHashMap()
output = new LinkedHashMap()
output.put 'key0', 'value0'
output.put 'key1', 'value1'
output.put 'key2', 'value2'

我个人反对 (我知道;这是一个强词) 重新为变量赋值。以下(丑陋的)模式是您代码中的主要邪恶根源之一:

def x = foo()
// do something with 'x'
...
x = bar()
// do something else with 'x'

这很容易使理解代码变得非常困难并引入错误。您必须不断关注 x 以确保它包含应有的值!真的! 只需创建另一个变量来保存第二个值;它绝对没有任何问题——64KB 内存的时代已经一去不复返了。

def fooX = foo()
// do something with 'fooX'
...
def barX = bar()
// do something with 'barX'

这使得阅读代码和理解其行为变得更加容易。

就个人而言,当我编写需要重新分配给变量的代码时,我很快意识到我组织代码的方式有问题。我只在极少数情况下这样做。