我经常读到不可能在迭代器上调用 Lambda 函数。直到现在我也一直抱着这样的信念。然而,阅读 Franco Ponticelli 和 Lee-McColl-Sylvester 所著的《Professional 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}
}
}
为什么它有效(至少在这里)
“在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 函数一起使用。或者事情总是这么简单?
最佳答案
在 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 配合使用。
祝你好运:)
关于迭代器(不是迭代器)上的 Lambda 迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25648390/