将Seq(Seq)分配给多个类型数组而不先将Seq分配给标量的正确语法是什么?Seq是否会以某种方式展平?这将失败:
class A { has Int $.r }
my A (@ra1, @ra2);
#create two arrays with 5 random numbers below a certain limit
#Fails: Type check failed in assignment to @ra1; expected A but got Seq($((A.new(r => 3), A.n...)
(@ra1, @ra2) =
<10 20>.map( -> $up_limit {
(^5).map({A.new( r => (^$up_limit).pick ) })
});
Run Code Online (Sandbox Code Playgroud)
rai*_*iph 12
TL; DR绑定比分配更快,因此也许这是针对您问题的最佳实践解决方案:
:(@ra1, @ra2) := <10 20>.map(...);
Run Code Online (Sandbox Code Playgroud)
简化,您的无效代码是:
(@listvar1, @listvar2) = list1, list2;
Run Code Online (Sandbox Code Playgroud)
在P6中缀=方式分配/从复制的权值列表中= 为一个或多个的容器上的变量离开的=。
如果左侧的变量绑定到Scalar容器,则它将接受一项。然后,复制过程开始针对下一个容器变量。
如果左侧的变量绑定到Array容器,则它将接受所有剩余值。因此,您的第一个数组变量同时接收list1和list2。这不是您想要的。
简化,这是克里斯托夫的答案:
@listvar1, @listvar2 Z= list1, list2;
Run Code Online (Sandbox Code Playgroud)
把=静置片刻,Z是中缀版本的zip程序。就像(一个物理zip在其左右两侧将连续的参数配对。当与运算符一起使用时,会将该运算符应用于该对。因此,您可以将上面的内容读取Z=为:
@listvar1 = list1;
@listvar2 = list2;
Run Code Online (Sandbox Code Playgroud)
任务完成。
但是分配到 Array容器中需要:
分别将尽可能多的单个列表项复制到容器中。(在示例代码中list1,list2每个代码包含5个元素,因此总共有10个复制操作。)
强迫容器根据需要调整大小以容纳物品。
将项目使用的内存加倍(原始列表元素以及复制到Array元素中的重复项)。
检查每个项目的类型是否匹配元素类型约束。
通常,分配比绑定要慢得多,而且占用的内存更多。
:(@listvar1, @listvar2) := list1, list2;
Run Code Online (Sandbox Code Playgroud)
该:=运营商的绑定在其右侧参数无论是在它的左边。
如果左侧只有一个变量,那么事情就特别简单。绑定后,变量现在精确地指向右边的内容。(这是特别简单和快速的—快速的类型检查就完成了。)
但这不是我们的情况。
绑定在其左侧也接受独立的签名文字。将:(...)在我的答案是一个独立的Signature文字。
(签名通常附加到不带冒号前缀的例程。例如,sub foo (@var1, @var2) {}该(@var1, @var2)部分是附加到例程的签名foo。但是如您所见,一个人可以单独编写一个签名,并在P6前面加上一对来让它知道它是一个签名。主要区别在于签名中列出的所有变量都必须已经声明。)
当左侧有签名文字时,绑定将根据与接收例程签名的例程调用中的绑定参数相同的逻辑进行。(实际上,它在编译器中执行相同的代码路径。)
因此,最终结果是变量获得了它们在此子对象中拥有的值:
sub foo (@listvar1, @listvar2) { }
foo list1, list2;
Run Code Online (Sandbox Code Playgroud)
也就是说效果与以下相同:
@listvar1 := list1;
@listvar2 := list2;
Run Code Online (Sandbox Code Playgroud)
再次,就像克里斯托夫的答案一样,工作完成了。
但是这次,我们将避免上一节末尾描述的大部分分配开销。
Chr*_*oph 11
不能完全确定是否是设计使然,但似乎发生的是两个序列都存储在中@ra1,而@ra2仍然为空。这违反了类型约束。
起作用的是
@ra1, @ra2 Z= <10 20>.map(...);
Run Code Online (Sandbox Code Playgroud)