我经常读到它无法在迭代器上调用Lambda函数。直到现在我仍然坚持这种信念。然而,阅读Franco Ponticelli和Lee-McColl-Sylvester撰写的专业Haxe一书,关于是什么让对象成为Iterable或Iterator让我想到了一个技巧,这似乎有用;至少在我刚测试过的简单案例中。
诀窍就是在Iterator类中声明一个iterator()函数,返回本身(很奇怪是的,但不是那种语无伦次)。
我不知道这是否适用于一般情况,但是这个简单的例子在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}
}
}
为什么会有效(至少在这里)
&#34;在haXe标准库中,定义了两个非常常用的typedef:Iterator和Iterable。
他们的定义如下:
typedef Iterator<T> = {
function hasNext() : Bool;
function next() : T;
}
typedef Iterable<T> = {
function iterator() : Iterator<T>;
}
&#34; - Franco Ponticelli和Lee-McColl-Sylvester的Haxe Professional
因此,将iterator()添加到Iterator类使其成为Iterable,并可与Lambda函数一起使用。或者这总是那么简单?
答案 0 :(得分:2)
查看Haxe存储库中的此(开放)问题:
Lambda should support Iterator as well as Iterable #1914
线程中的最终注释实际上就是你所建议的 - 它可以工作,但改变“迭代器”的定义,以便每个迭代器本身都是“可迭代的”是一个突破性的变化,不可能改变在Haxe期间3.也许对于Haxe 4:)
另一个选项是使用摘要(允许隐式转换)创建一个适用于Iterable和Iterator的类型“Iter”:
abstract Iter<T>(Iterator<T>) from Iterator<T> to Iterator<T> {
inline function new(it:Iterator<T>)
this = it;
@:from static public inline function fromIterable(it:Iterable<T>) {
return new Iter(it.iterator());
}
}
我在对该问题的评论中写到了这一点:https://github.com/HaxeFoundation/haxe/issues/1914#issuecomment-19380450
您可以使用Iter创建自己的自定义Lambda助手,该助手适用于Iterable和Iterator。
祝你好运:)