You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非标量变量的解构赋值:绑定与赋值行为差异及疑问

Raku绑定与赋值解构的差异问题

绑定行为符合预期,但赋值行为却不符合:

my ($a, @b, $c) := (42, <a b c>, 42);
say [$a, @b, $c]; # OUTPUTS: [42 (a b c) 42]
my ($d, @e, $f)  = (42, <a b c>, 42);
say [$d, @e, $f]; # OUTPUTS: [42 [(a b c) 42] (Any)]

我假设带有@(或%)符号的变量会捕获所有剩余值。

现提出以下技术问题:

  1. 我的上述假设是否正确,或是该机制另有运作逻辑?
  2. 能否在赋值操作中实现与绑定操作类似的解构行为?

问题1解答

你的假设不正确,绑定(:=)和赋值(=)的解构逻辑完全不同:

  • 绑定操作:变量直接关联到右侧对应位置的原有值,不复制数据。($a, @b, $c) := ... 中每个变量分别绑定到右侧列表的三个元素,@b 绑定到第二个元素(<a b c>列表),因此结果符合预期。
  • 赋值操作:将右侧数据复制到左侧变量,遵循扁平化解构规则:左侧的数组变量@e会吸收右侧当前位置开始的所有剩余元素。示例中$d取第一个元素42后,剩下的<a b c>和42都被@e吸收,导致@e变为[(a b c) 42],$f无值可取则默认是Any。

问题2解答

可以通过两种方式在赋值时实现类似绑定的解构行为:

  1. 用括号包裹数组变量:让数组变量仅接收右侧对应位置的单个元素,而非剩余所有值:
my ($d, (@e), $f) = (42, <a b c>, 42);
say [$d, @e, $f]; # OUTPUTS: [42 (a b c) 42]

这里(@e)表示仅取右侧第二个元素<a b c>赋值给@e,后续的42留给$f。

  1. 使用逐项赋值:明确指定每个变量对应的右侧元素:
my ($d, @e, $f) = (42 => $d, <a b c> => @e, 42 => $f);
say [$d, @e, $f]; # OUTPUTS: [42 (a b c) 42]

这种方式直接一一对应赋值,避免数组变量吸收剩余元素的行为。

内容的提问来源于stack exchange,提问作者fingolfin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:42:09