Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
迭代器上的Lambda迭代(不是Iterable)_Lambda_Iterator_Haxe_Iterable - Fatal编程技术网

迭代器上的Lambda迭代(不是Iterable)

迭代器上的Lambda迭代(不是Iterable),lambda,iterator,haxe,iterable,Lambda,Iterator,Haxe,Iterable,我经常读到在迭代器上调用Lambda函数是不可能的。直到现在,我一直生活在这个信念中。然而,读了弗朗哥·蓬蒂切利和李·麦考尔·西尔维斯特的《专业哈克斯》一书,讲述了是什么让一个对象成为可编辑对象或迭代器,让我想到了一个技巧,它似乎奏效了;至少在我刚刚测试的简单案例中 诀窍就是在迭代器类中声明一个迭代器()函数,并返回它自己(奇怪的是,但不是那么不连贯) 我不知道这在一般情况下是否有效,但这个简单的示例在Haxe 2和Haxe 3()上编译并运行良好: 使用Lambda; 第二类{ var-min

我经常读到在迭代器上调用Lambda函数是不可能的。直到现在,我一直生活在这个信念中。然而,读了弗朗哥·蓬蒂切利和李·麦考尔·西尔维斯特的《专业哈克斯》一书,讲述了是什么让一个对象成为可编辑对象或迭代器,让我想到了一个技巧,它似乎奏效了;至少在我刚刚测试的简单案例中

诀窍就是在迭代器类中声明一个迭代器()函数,并返回它自己(奇怪的是,但不是那么不连贯)

我不知道这在一般情况下是否有效,但这个简单的示例在Haxe 2和Haxe 3()上编译并运行良好:

使用Lambda;
第二类{
var-min:Int;
var-max:Int;
新的公共内联函数(最小值:Int,最大值:Int){
this.min=min;
this.max=max;
}
公共内联函数hasNext(){return min
为什么有效(至少在这里)

在haXe标准库中,定义了两个非常常用的typedef:Iterator和Iterable

其定义如下:

typedef Iterator<T> = { 
    function hasNext() : Bool; 
    function next() : T;
}
typedef Iterable<T> = {
    function iterator() : Iterator<T>; 
}
typedef迭代器={
函数hasNext():Bool;
函数next():T;
}
typedef Iterable={
函数迭代器():迭代器;
}
“-佛朗哥·蓬蒂切利和李·麦考尔·西尔维斯特创作的哈克斯专业版

因此,将迭代器()添加到迭代器类中可以使其可移植,并可用于Lambda函数。或者这总是那么简单?

在Haxe存储库中查看此(开放)问题:

线程中的最后一条注释实际上是您所建议的,它可能会起作用,但是更改“迭代器”的定义,使每个迭代器本身都是“可编辑的”,这是一个突破性的更改,在Haxe 3期间不太可能更改。也许对于Haxe 4:)

另一个选项是使用允许隐式转换的抽象来创建一个类型“Iter”,该类型可与Iterable和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());
  } 
}
将Iter(迭代器)从一个迭代器抽象到另一个迭代器{
内联函数new(it:Iterator)
这个=它;
@:from静态公共内联函数fromIterable(it:Iterable){
返回新的Iter(it.iterator());
} 
}
我在对该问题的评论中写道:

您可以使用Iter创建自己的自定义Lambda助手,该助手可以同时使用Iterable和Iterator


祝你好运:)

Edit:我的测试表明它甚至可以用于更复杂的情况(模板迭代器类优于继承其他类的模板类等)。只要确保编写
函数迭代器():类{}
的名称,而不是
函数迭代器():迭代器{}
,您就会没事(否则在第二种情况下,它会抱怨迭代器没有
Lambda.filter
或您尝试使用的
任何其他同态方法),这是一次很好的讨论。但是我真的不理解你用
抽象
,用
从迭代器到迭代器
的解决方案。我猜这是Haxe 3中的新内容。我不知道这是否会在转换阶段导致问题,但如果不是,我认为所有迭代器都应该是可移植的。在Java这样的语言中分离这两个概念是有意义的,但是对于一种叫做Haxe(“hacks”)的语言来说,坚持迭代器的正统概念只是一种限制,所以我也主张在Haxe4中使用迭代器。顺便问一下,如果它们都是可移植的,这真的是一个突破性的变化吗?诚然,它将从根本上改变迭代器的概念,因此有充分的理由不这样做,但我并没有立即看到它将如何实际破坏事物(也许我没有足够的想象力:p)。唯一会破坏的是如果你有自定义迭代器。因此,如果我现在有一个与Iterable匹配的类,但是Iterable也需要一个迭代器():Iterable函数,那么我的自定义迭代器就不再是迭代器了。我个人不在我的代码中使用自定义迭代器,但我相信有些人会。。。除此之外,它不会真正破坏任何东西:)Jason:以前我认为它们没有那么有用,但最近我将我的线条绘制功能移植到了迭代器,现在如果我想检测某个方向上的障碍物,例如投掷箭头,我不需要再计算线条上的所有点。因此,对于带有网格的2d游戏,我认为自定义迭代器非常有用,如果它们可以与Lambda一起使用,那就更有用了。
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());
  } 
}