我經常讀到,在迭代器上調用Lambda函數是不可能的。直到現在,我仍然堅信這種信念。然而,閱讀由Franco Ponticelli和Lee-McColl-Sylvester撰寫的專業Haxe關於什麼使得Iterable或迭代器成爲可能或者迭代器的原因讓我想到了一個技巧,這看起來似乎有效;至少在我剛測試的簡單情況下。Iterator上的Lambda迭代(不是可迭代的)
訣竅很簡單,就是聲明一個迭代()函數內的迭代器類,返回本身(奇怪的是,但不是語無倫次)。
我不知道這是否會在一般情況下工作,但這個簡單的例子編譯和兩個HAXE 2和3 HAXE工作正常(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定義:迭代器和可迭代
它們的定義如下:
typedef Iterator<T> = {
function hasNext() : Bool;
function next() : T;
}
typedef Iterable<T> = {
function iterator() : Iterator<T>;
}
「 - HAXE專業佛朗哥Ponticelli和Lee-麥科爾-西爾威斯特
因此增加迭代器()到一個Iterator類使得它可迭代,可使用的與lambda函數。還是那麼簡單?
**編輯**:我的測試表明,它甚至更復雜的情況(模板化的迭代類在模板類繼承他人等)的作品。只要確保編寫'function iterator():NameOfTheClass {}'而不是'function iterator():Iterator {}',你會沒事的(否則在第二種情況下它會抱怨迭代器沒有'Lambda。過濾器「或其他任何你嘗試使用的同態方法)。 –
2014-09-03 19:40:58