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

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

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

是否有一种编程方法来检查标量是否不可变,而无需尝试更改它并查看它是否有效?

回答

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

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

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

据我所知,没有办法区$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»

  • 事实上,`constant $a = 42` 和 `my $a := 42` 之间没有运行时差异。重新绑定到它的可能性是在编译时确定的,当编译器“看到”左侧被定义为“常量”并决定抛出“无法在左侧使用绑定运算符”错误时。
  • “对于真正的常量 `$a`,您应该使用 `constant $a` 或将 `$a` 更改为无符号变量(`my a = 6`)。” 我认为脚注是有序的。(或者可能是一个略带术语技巧的网站。)您所说的恒定性仅与绑定到变量的值的*引用*有关,而不是与值本身有关。考虑`常量 foo = 42; foo 确实有作用 { method Str { '99' } }; 说 foo; #99`。虽然你可能(非常正确地)说我所做的只是改变了那个特定的“42”的方法,但关键是 Raku 还不支持真正的绝对不变性。

回答

另一种方式,使用多分派:

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


以上是有没有办法检测某些东西是否不可变?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>