为什么我无法在 Raku 中进行赋值后进行迭代?

mar*_*rwy 12 raku

给出以下代码,如果 Buf 已分配给变量,我似乎无法迭代它,除非我将其转换为列表,即使它不是惰性序列。是什么赋予了?

    my $file = open $path, bin => True;
    $_.chr.say for $file.read: 8; # works well

    my $test = $file.read: 8;
    $_.chr.say for $test; # fails with "No such method 'chr' for invocant of type 'Buf[uint8]'"
    $_.chr.say for $test.list; # works well
    $test.is-lazy.say; # False
Run Code Online (Sandbox Code Playgroud)

Eli*_*sen 14

失败的原因是:

my $test = $file.read: 8;
Run Code Online (Sandbox Code Playgroud)

Buf返回的值$file.read放入变量中Scalar,即容器内。容器化被解释为for逐项列出,被视为单个项目。所以:

.chr.say for $test;
Run Code Online (Sandbox Code Playgroud)

您是.chr在整个元素上调用该方法Buf,而不是在单个元素上调用该方法。

对此有多种解决方案:

  1. 确保没有容器:
my $test := $file.read: 8;
Run Code Online (Sandbox Code Playgroud)

这可以确保通过绑定.Buf

  1. 让它看起来像一个数组
my @test := $file.read: 8;
Run Code Online (Sandbox Code Playgroud)

基本上与 1 相同,将 设为@test的别名Buf。请注意,这也应该使用绑定,否则您将得到与您看到的相同的效果。

  1. 让它像 Iterable 一样工作
.chr.say for @$test;
Run Code Online (Sandbox Code Playgroud)

通过添加前缀,@你可以告诉它迭代它。这基本上是$test.list您已经找到的解决方法的语法糖。

关于$test.is-lazy.say,这False几乎适用于任何事物,例如42.is-lazy.say; # False,所以这并不能告诉你太多:-)