有没有办法检测某些东西是否不可变?
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
在 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