每次循环分配新值时 DRY
DRY when assigning new value each loop
考虑一个函数 query_item
returns 要处理的对象或 null
如果不再处理任何对象。
let item = query_item();
while(item !== null){
process(item);
item = query_item();
}
显然,这是对 DRY(不要重复你自己)的轻微违反,主要通过将 query_item()
作为专用函数来缓解。
我知道在这个简单的案例中,清晰比防止重复重要得多。
不过,有没有办法不用重复赋值就可以写出这样的循环?
我唯一想出的方法是 for 循环方法,但它具有相同的重复性,而且——至少在我看来——有点难读。
for(let item = query_item();
item !== null;
item = query_item()
){
process(item);
};
漂亮一点?
let item;
do {
item = query_item();
if (item) process(item);
} while (item !== null)
这是在 while
条件中使用赋值的标准场景:
let item;
while (item = query_item()) {
process(item);
}
或者,如果您想明确说明:
let item;
while ((item = query_item()) !== null) {
process(item);
}
您也可以使用具有相同方法的 for
循环,这也为您提供 let
:
的块作用域
for (let item; item = query_item(); ) {
process(item);
}
对于javascript我相信你可以写:
while(let item = query_item() && item){
process(item);
}
如果你想完全避免这种奇怪的赋值并获得尽可能简单的循环语法,你可以考虑使用 ES6 iterator:
function query_items() {
return {
[Symbol.iterator]() {
return this;
},
next() {
return {
value: query_item(),
get done() { return this.value === null }
};
}
};
}
for (let item of query_items()) {
process(item);
}
或者甚至更好地立即将 query_items
实施为 generator function。
替代...
let item;
while (item = query_item()) {
process(item);
}
...是一个 generator function,它在遇到 null
值时终止:
function* iterate(cb) {
let next = cb();
if (next === null) return;
yield next, yield* iterate(cb);
}
for (let item of iterate(query_item)) {
process(item);
}
考虑一个函数 query_item
returns 要处理的对象或 null
如果不再处理任何对象。
let item = query_item();
while(item !== null){
process(item);
item = query_item();
}
显然,这是对 DRY(不要重复你自己)的轻微违反,主要通过将 query_item()
作为专用函数来缓解。
我知道在这个简单的案例中,清晰比防止重复重要得多。
不过,有没有办法不用重复赋值就可以写出这样的循环?
我唯一想出的方法是 for 循环方法,但它具有相同的重复性,而且——至少在我看来——有点难读。
for(let item = query_item();
item !== null;
item = query_item()
){
process(item);
};
漂亮一点?
let item;
do {
item = query_item();
if (item) process(item);
} while (item !== null)
这是在 while
条件中使用赋值的标准场景:
let item;
while (item = query_item()) {
process(item);
}
或者,如果您想明确说明:
let item;
while ((item = query_item()) !== null) {
process(item);
}
您也可以使用具有相同方法的 for
循环,这也为您提供 let
:
for (let item; item = query_item(); ) {
process(item);
}
对于javascript我相信你可以写:
while(let item = query_item() && item){
process(item);
}
如果你想完全避免这种奇怪的赋值并获得尽可能简单的循环语法,你可以考虑使用 ES6 iterator:
function query_items() {
return {
[Symbol.iterator]() {
return this;
},
next() {
return {
value: query_item(),
get done() { return this.value === null }
};
}
};
}
for (let item of query_items()) {
process(item);
}
或者甚至更好地立即将 query_items
实施为 generator function。
替代
let item;
while (item = query_item()) {
process(item);
}
...是一个 generator function,它在遇到 null
值时终止:
function* iterate(cb) {
let next = cb();
if (next === null) return;
yield next, yield* iterate(cb);
}
for (let item of iterate(query_item)) {
process(item);
}