Lambda迭代遍历迭代器(不可迭代) [英] Lambda iteration over an Iterator (not an Iterable)
问题描述
我经常读到在迭代器上调用Lambda函数是不可能的.直到现在我一直信奉这种信念.但是,阅读佛朗哥·庞蒂塞利(Franco Ponticelli)和李·麦科尔·西尔维斯特(Lee-McColl-Sylvester)所著的Professional Haxe一书,关于使对象成为可迭代对象或迭代器的原因使我想到了一个技巧,这似乎行得通.至少在我刚刚测试过的简单情况下.
I often read it's impossible to call Lambda functions on iterators. And I lived in that belief until now. However reading the book Professional Haxe by Franco Ponticelli and Lee-McColl-Sylvester about what makes an objet an Iterable or an Iterator made me think of one trick, that seems to work; at least in the simple case I just tested.
诀窍很简单,就是在Iterator类的内部声明一个Iterator()函数 ,并返回 itself (很奇怪,但不是那么不连贯).
The trick is simply to declare an iterator() function inside the Iterator class, returning itself (weird yes, but not that incoherent).
我不知道这在一般情况下是否行得通,但是这个简单的示例可以在Haxe 2和Haxe 3上编译并正常工作(
I don't know if this will work in the general case, but this simple examples compiles and works fine on both Haxe 2 and 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.
"In the haXe standard library, two very commonly used typedefs are defined: Iterator and Iterable.
它们的定义如下:
typedef Iterator<T> = {
function hasNext() : Bool;
function next() : T;
}
typedef Iterable<T> = {
function iterator() : Iterator<T>;
}
"-Franco Ponticelli和Lee-McColl-Sylvester的Haxe Professional
" - Haxe Professional by Franco Ponticelli and Lee-McColl-Sylvester
因此,将iterator()添加到Iterator类使其可迭代,并且可与Lambda函数一起使用.还是总是那么简单?
Therefore adding iterator() to an Iterator class makes it Iterable, and usable with Lambda functions. Or is that always so simple?
推荐答案
在Haxe存储库中查看此(开放)问题:
Check out this (open) issue on the Haxe repository:
Lambda应该支持Iterator以及Iterable#1914
该线程中的最终注释实际上是您的建议-它可以起作用,但是更改迭代器"的定义以使每个迭代器本身都是可迭代的"是一项重大更改,不可能更改在Haxe 3期间.也许在Haxe 4期间:)
The final comment in the thread is actually what you're suggesting - and it could work, but changing the definition of "Iterator" so that every iterator is itself "iterable" is a breaking change and won't likely be changed during Haxe 3. Maybe for Haxe 4 :)
另一种选择是使用允许隐式转换的抽象来创建可与Iterable和Iterator一起使用的类型"Iter":
The other option is using abstracts, which allow implicit casting, to create a type "Iter" that works with both Iterable and Iterator:
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
I wrote about this in a comment on that issue: https://github.com/HaxeFoundation/haxe/issues/1914#issuecomment-19380450
您可以使用Iter创建可与Iterable和Iterator一起使用的自定义Lambda帮助程序.
You could use Iter to create your own custom Lambda helper that works with both Iterable and Iterator.
祝你好运:)
这篇关于Lambda迭代遍历迭代器(不可迭代)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!