我经常读到在迭代器上调用 Lambda 函数是不可能的。直到现在我也一直抱着这样的信念。然而,阅读 Franco Ponticelli 和 Lee-McColl-Sylvester 所著的《Professional Haxe》一书,了解如何使对象成为 Iterable 或 Iterator,这让我想到了一个似乎有效的技巧:至少在我刚刚测试的简单情况下是这样。
诀窍是简单地声明一个 iterator() 函数insideIterator 类,返回itself(是的,很奇怪,但不是那么不连贯)。
我不知道这在一般情况下是否有效,但是这个简单的示例在 Haxe 2 和 Haxe 3 上都可以编译并正常工作(http://try.haxe.org/#b764F http://try.haxe.org/#b764F):
using Lambda;
class IntIter2 {
var min : Int;
var max : Int;
public inline function new( min : Int, max : Int ) {
this.min = min;
this.max = max;
}
public inline function hasNext() { return min < max; }
public inline function next() { return min++; }
// here goes the magic/weirdness/abomination
public function iterator():IntIter2 { return this; }
}
class Test {
public static function main() {
var evenNumbers = new IntIter2(3, 10)
.filter( function (n:Int):Bool return n % 2 == 0 )
.list() // unneeded, in fact...
;
trace(evenNumbers.toString());
// list even numbers in the series, ie {4, 6, 8}
}
}
为什么它有效(至少在这里)
“在 haXe 标准库中,定义了两个非常常用的 typedef:Iterator 和 Iterable。
它们的定义如下:
typedef Iterator<T> = {
function hasNext() : Bool;
function next() : T;
}
typedef Iterable<T> = {
function iterator() : Iterator<T>;
}
” - Haxe Professional 由 Franco Ponticelli 和 Lee-McColl-Sylvester 设计
因此,将 iterator() 添加到 Iterator 类使其成为可迭代的,并可与 Lambda 函数一起使用。或者事情总是这么简单?