我正在尝试制作一个迭代器,然后从中构建一个序列,但是它没有按照我认为的方式运行。怎么了?
这是我的基础班:
class Foo {
has $.x = 0;
has $.max = 3;
method val() {
(++$!x > $!max) ?? () !! ($!x, "string $!x")
}
}
my $foo = Foo.new;
say $foo.val.perl for ^4;
# (1, "string 1")
# (2, "string 2")
# (3, "string 3")
# ()
它只会迭代到max,然后返回(),以我认为的方式工作。
然后我从中构建一个Iterator,仅使用一个pull-one()
方法。
class Foo-Iterator does Iterator {
has Foo $.foo;
method pull-one() {
$!foo.val || IterationEnd
}
}
my $iter = Foo-Iterator.new(foo => Foo.new);
$iter.pull-one.perl.say for ^4;
# (1, "string 1")
# (2, "string 2")
# (3, "string 3")
# IterationEnd
它仍然按照我期望的方式运行。
如果我使用Seq访问它,它仍然可以正常工作:
.perl.say for Seq.new: Foo-Iterator.new(foo => Foo.new);
# (1, "string 1")
# (2, "string 2")
# (3, "string 3")
这仍然是我期望看到的,与迭代器返回的结果相同。
最后,我将Seq存储在@
变量中并打印结果:
my @seq = Seq.new: Foo-Iterator.new(foo => Foo.new);
.perl.say for @seq;
# $(4, "string 1")
# $(4, "string 2")
# $(4, "string 3")
这是怎么回事?似乎使用的是变量的后一个值,而不是使用在推入式call()时它具有的值(字符串将其强制为值)。 Seq
是否将其作为容器而不是值返回?这种懒惰在起作用吗,直到请求时才拉动,以便获得更高的值?
如果我让val()
返回+$!x
而不是返回$!x
,那似乎是在获取价值并给了我想要的东西,我只是想了解自己的行为
答案 0 :(得分:7)
我对C:\Users\your_user_name\AppData\Local\Atlassian\SourceTree\git_local\usr\bin
进行了4处更改:keytool -alias MyKey -exportcert -keystore MyKey.keystore | C:\Users\your_user_name\AppData\Local\Atlassian\SourceTree\git_local\usr\bin\xxd -p | C:\Users\your_user_name\AppData\Local\Atlassian\SourceTree\git_local\usr\bin\tr -d "[:space:]"
,Foo
,does Iterator
,然后用pull-one
断定IterationEnd
。 >
当您真的要在容器内传递值时,您的方法正在传递%!x
的容器,因此它需要<>
。
您在其余的代码中没有注意到它的原因是,数组分配是唯一的$!x
。
我做了其余的更改,因为它已经具有状态,并且只能运行一次。 $!x<>
到底应该如何工作。对于您的代码,为eager
添加基本上仅重命名方法的另一个对象是没有意义的。
Iterator
现在可以使用
Iterator
假设您的示例太简单了,并且有一个单独的class Foo does Iterator {
# ^-----------^
has $.x = 0;
has $.max = 3;
method pull-one() {
# ^------^
(++$!x > $!max) ?? IterationEnd !! ($!x<>, "string $!x")
# ^----------^ ^^
}
}
的充分理由,那么为什么要使用变异的my $seq = Seq.new( Foo.new );
for $seq<> { .say }
# (1 string 1)
# (2 string 2)
# (3 string 3)
my @seq = Seq.new( Foo.new );
for @seq { .say }
# (1 string 1)
# (2 string 2)
# (3 string 3)
方法呢?
Iterator
现在可以使用它。
val