声明一个带有空映射的变量,然后为它分配一个不同的对象是一种有效的模式吗?
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'
这使得阅读代码和理解其行为变得更加容易。
就个人而言,当我编写需要重新分配给变量的代码时,我很快意识到我组织代码的方式有问题。我只在极少数情况下这样做。
我们正在开发一个 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'
这使得阅读代码和理解其行为变得更加容易。
就个人而言,当我编写需要重新分配给变量的代码时,我很快意识到我组织代码的方式有问题。我只在极少数情况下这样做。