Raku多变量绑定操作符行为疑问:需同声明行执行且似为赋值
Perl 6绑定操作符
:=多变量场景的行为详解 刚好对Perl 6的容器绑定机制比较熟悉,来拆解一下你遇到的这个问题:
先搞懂:=到底在做什么
Perl 6里的:=是容器绑定操作符,和普通赋值=完全不是一回事:
=是把值复制到变量的容器里,相当于“拷贝一份给你”;:=是让两个变量共享同一个容器,相当于“咱们俩用同一个储物盒,你改里面的东西我也能看到”。
为什么分开声明和绑定会报错?
你写的这段代码:
my ($v1, $v2); ($v1, $v2) := ($i1, $i2);
问题出在第一行my ($v1, $v2);——这行已经给$v1和$v2各自创建了独立的Scalar容器。等你第二行用:=的时候,左边的($v1, $v2)是两个已经存在的容器组成的列表,而Perl 6的绑定规则里,:=的左操作数必须是还没创建容器的声明式变量(列表)。
简单说就是:绑定是要在变量“出生”的时候就把它和目标容器挂钩,不能等它已经有了自己的容器再强行改挂钩关系——编译器不允许这种操作,所以直接报错。
为什么同声明一行的代码没实现真正绑定?
你给出的“成功示例”其实是个假象:
my $i1 = 1; my $i2 = 2; my ($v1, $v2) := ($i1, $i2);
这里右边的($i1, $i2)是一个值列表,不是容器列表。当你在声明行用:=的时候,编译器会为$v1和$v2创建新容器,然后把右边列表里的值分别塞进去——本质还是值赋值,只是写法用了:=而已,并没有共享容器。
如果想要真正实现多变量绑定,你得显式获取变量的容器,比如这样写:
my $i1 = 1; my $i2 = 2; my ($v1, $v2) := ($i1, $i2).map: *.container; # 拿到$i1和$i2的容器 say $v1.WHICH eq $i1.WHICH; # 输出True,证明是同一个容器 $i1 = 11; say $v1; # 输出11,现在才是真正的绑定效果
关键规则总结
- 用
:=做绑定,必须把变量声明(my/our/has)和绑定写在同一行——因为只有这时候编译器才能跳过创建新容器的步骤,直接把右边的容器关联到左边变量上。 - 如果右边是普通值列表,哪怕写在声明行,
:=也会退化为值赋值;要实现容器绑定,得显式获取目标变量的容器。
内容的提问来源于stack exchange,提问作者jakar
相关产品推荐
相关产品推荐

