【发布时间】:2014-10-28 04:39:57
【问题描述】:
我经常读到不可能在迭代器上调用 Lambda 函数。直到现在我都活在这种信念中。然而,阅读 Franco Ponticelli 和 Lee-McColl-Sylvester 所著的《Professional Haxe》一书,关于什么使对象成为 Iterable 或 Iterator 的内容让我想到了一个似乎有效的技巧;至少在我刚刚测试的简单案例中。
诀窍就是在 Iterator 类内声明一个 iterator() 函数,返回 itself(很奇怪,但不是那么不连贯)。
我不知道这是否适用于一般情况,但这个简单的示例可以在 Haxe 2 和 Haxe 3 上编译并正常工作 (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>;
}
" - Franco Ponticelli 和 Lee-McColl-Sylvester 的 Haxe Professional
因此,将 iterator() 添加到 Iterator 类使其可迭代,并可与 Lambda 函数一起使用。还是总是这么简单?
【问题讨论】:
-
编辑:我的测试表明它甚至适用于更复杂的情况(模板化迭代器类优于模板化类继承其他类等)。只要确保写
function iterator():NameOfTheClass {}而不是function iterator():Iterator<SomeType> {}就可以了(否则在第二种情况下,它会抱怨迭代器没有Lambda.filter或您尝试的任何其他同态方法using)。
标签: lambda iterator haxe iterable