有没有办法检测某些东西是否不可变?

Is there a way to detect whether something is immutable?

在 Raku 中,标量可能是不可变的,也可能是实际变量:

 my $a := 6;  # constant
 my $b  = 6;  # variable

是否有一种程序化的方法来检查标量是否不可变,而不是仅仅尝试更改它并查看它是否有效?

首先,稍微修正一下术语(不是吹毛求疵,只是因为这个领域有点棘手,准确使用我们的术语会有所帮助)。

my $a := 6是一个常量是不太对的;该表达式 绑定 $a 到值 6,这会阻止您 分配 一个不同的值给 $a (用= 运算符)。但是,您仍然可以将新值重新绑定到 $a(使用 := 运算符)。这意味着 $a 在某种意义上仍然可以被改变——或者至少可以指向新的东西。对于真正的常量 $a,您应该使用 constant $a 或将 $a 更改为无符号变量 (my \a = 6).

现在回答您的问题:要确定 $a 是否绑定或分配给一个值,您可以使用 $a.VAR.WHAT。如果 $a 被赋值,这将 return 容器类型, (Scalar);如果它是绑定的,那么它将 return 绑定值的类型。

据我所知,没有一种方法可以区分 $a 绑定到一个值和一个常量,尽管我很乐意在这一点上是错误的。

下面的代码说明了我刚才所说的内容:

my $a = 1;
say $a.VAR.WHAT; # OUTPUT: «(Scalar)»
$a = 2;
say $a;          # OUTPUT: «2»

my $b := 1;
say $b.VAR.WHAT;# OUTPUT: «(Int)»
$b := 2;
say $b;          # OUTPUT: «2»

constant $c = 1;
say $c.VAR.WHAT; # OUTPUT: «(Int)»
# $c := 2; ILLEGAL 
say $c;          # OUTPUT: «1»

另一种方式,使用multiple dispatch:

my $a := 6;  # constant
my $b  = 6;  # variable

multi sub mutable($ is rw) { True }
multi sub mutable($) { False }

say mutable($a); # False
say mutable($b); # True
say mutable(42); # False