为什么数组作为可变参数传递但标量不是?

Why are arrays passed as arguments mutable but scalars are not?

知道了:

#! /usr/bin/env raku
use v6;

multi blah (@arg) { @arg = 7; }
multi blah ($arg) { $arg = '3'; }

my @array = 1, 2, 3;
blah @array;
say @array;

my $string = 'onetwothree';
blah $string;
say $string;

得到这个:

[7]
Cannot assign to a readonly variable or a value
  in sub blah at ./chop.raku line 5
  in block <unit> at ./chop.raku line 12

我发现这种行为令人惊讶,尤其是在函数范围之外更改数组的能力。

有人可以解释为什么我可以更改传递给函数而不是标量的数组参数吗?有没有办法让数组在传递给函数时只读?有什么方法可以使传递给函数的标量可变吗?

Can someone please explain why I can change an array argument passed to a function but not a scalar?

传递给函数的参数是只读的(默认情况下;更多内容见下文),因此通常无法更改。您可以修改 Array 的原因是 Array 本身是可变的(有关详细信息,请参阅文档中的 Lists, sequences, and arrays 页面)。这意味着,即使您无法更改 Array 本身 ,您仍然可以更改 in [=12] 的值=].

And is there a way to make arrays read only when passed to a function?

List 是 Raku 的位置数据的不可变类型(有点;它不是深度不可变的,但这超出了这里的范围)。如果将 List 传递给函数,该函数将无法修改该列表的内容。例如,此代码会引发错误:

my @l is List = (1, 2, 3);
sub f(@var) { @var[1] = 42 }
f @l;

Is there any way to make a scalar passed to a function mutable?

有两种方法,具体取决于您想要哪种可变性:您可以使用 is rw and is copy traits。例如,您可以像这样声明一个函数:

sub f($a is copy, $b is rw) {...}

该声明允许 &f 修改 $a$b。但是对于 $a&f 正在修改其自己的本地副本,不会对其调用者看到的 $a 的值产生任何影响。然而,对于 $b&f 正在修改共享状态,它对 $b 所做的任何更改即使在 &f.

的范围之外也是可见的