我有意避免使用该术语,defined因为变量很可能具有已定义的值,但该.defined方法将返回 false(例如,Failures)。
有什么方法可以确定变量是否已为其设置了值?
my $foo;
say $foo; # (Any), its type object, no value assigned
my Str $bar;
say $bar; # (Str), its type object, no value assigned
my $abc = Str;
say $abc; # (Str), the type object we assigned to $abc
Run Code Online (Sandbox Code Playgroud)
我们如何区分$bar(未设置值,输入为Str)和$abc(值设置为Str)?
鉴于$bar.WHICH == $abc.WHICH, but $bar.VAR.WHICH !== $abc.VAR.WHICH, 和类似的方法.defined将为每个返回 false ,是否有任何快速简便的方法来确定存在一个设置值?
我认为它可以根据默认值进行检查,但是没有办法区分由于未设置和在代码中设置的值。
变量总是被设置为某种值。
如果您不将其设置为值,则会为您选择一个值。
具体来说,它将被设置为默认值。
(如果您不选择默认值,它将被设置为类型对象。)
my $abc;
say $abc.VAR.default.raku;
# Any
Run Code Online (Sandbox Code Playgroud)
my Int $def = 42;
say $def.VAR.default.raku;
# Int
Run Code Online (Sandbox Code Playgroud)
my $ghi is default(42) = 2;
say $ghi.VAR.default.raku;
# 42
Run Code Online (Sandbox Code Playgroud)
你所要求的并不是 Raku 真正支持的。
不过,您可能可以伪造一些接近的东西。
(每个实例Mu.new都是唯一的。)
sub is-not-set ( Mu $_ is raw ) {
$_.self =:= $_.VAR.default
}
my $abc is default(Mu.new);
my $def is default(Mu.new) = Any;
my $ghi is default(Mu.new) = Mu.new;
say is-not-set $abc; # True
say is-not-set $def; # False
say is-not-set $ghi; # False
Run Code Online (Sandbox Code Playgroud)
问题是分配Nil也会将其设置为默认值。
$def = Nil;
say is-not-set $def; # True
Run Code Online (Sandbox Code Playgroud)
就像查找默认值并分配它一样。
$ghi = $ghi.VAR.default;
say is-not-set $ghi; # True
Run Code Online (Sandbox Code Playgroud)
我不认为你应该担心这些事情。
如果您真的需要在第一次分配给变量时发生某些事情,您可以执行以下操作:
my $abc := Proxy.new(
# this FETCH only needs to return the default
# as this Proxy gets replaced upon the first assignment
FETCH => -> $ { Any },
STORE => -> $, $value {
# replace the Proxy with a new Scalar
$abc := do { my $abc = $value };
say 'first assignment just happened'
},
);
say $abc;
# Any
$abc = 1;
# first assignment just happened
say $abc;
# 1
$abc = 2;
say $abc;
# 2
Run Code Online (Sandbox Code Playgroud)
该do块就在那里,以便$abc.VAR.name返回$abc.
否则你可以只写$abc := my $ = $value.
我认为这两个值是相同的,但容器具有不同的类型约束。
尝试
my Str $foo;
my $bar = Str;
use Test;
cmp-ok $bar, &[===], $foo, 'The values are identical';
isa-ok $bar, Str;
isa-ok $foo, Str;
isa-ok $bar.VAR.of, Mu;
nok $bar.VAR.of.isa(Str), 'The container $bar is not of Str' ;
isa-ok $foo.VAR.of, Str;
done-testing();
Run Code Online (Sandbox Code Playgroud)
ok 1 - The values are identical
ok 2 - The object is-a 'Str'
ok 3 - The object is-a 'Str'
ok 4 - The object is-a 'Mu'
ok 5 - The container $bar is not of Str
ok 6 - The object is-a 'Str'
1..6
Run Code Online (Sandbox Code Playgroud)
my Str $bar并my $bar = Str产生相同的结果,两者都是 Str 类型,但没有确定的值。Str是类型对象,而不是值。
.definedTrue如果您给出$bar一个确定的值,例如"Str"(请注意裸字周围的引号),则会返回。