gpt4 book ai didi

raku - 在 raku 中取消绑定(bind)或取消定义变量

转载 作者:行者123 更新时间:2023-12-04 04:28:37 25 4
gpt4 key购买 nike

看了Raku的文档,才发现this用于取消定义变量。我相信在 Raku 中,赋值和绑定(bind)之间存在差异。
定义和取消定义标量很容易。

> my $n
(Any)
> $n.defined
False
> $n = 3
3
> $n.defined
True
> $n = Nil
(Any)
> $n.defined
False
当变量被绑定(bind)时,这是不可能的。
> my $k := 5
5
> $k := Nil
===SORRY!=== Error while compiling:
Cannot use bind operator with this left-hand side
at line 2
------> <BOL>⏏<EOL>
> $k = Nil
Cannot assign to an immutable value
in block <unit> at <unknown file> line 1
对于数组或散列,我可以清空它,但变量仍然被定义。
对于函数,当您使用 sub 定义函数时,您不能取消定义它,但您可以使用匿名函数。
> my &pera = -> $n { $n + 2}
-> $n { #`(Block|140640519305672) ... }
> &pera = Nil
(Callable)
> &pera.defined
False

> my &pera = -> $n { $n + 2}
-> $n { #`(Block|140640519305672) ... }
> &pera = Nil
(Callable)
> &pera.defined
False
> sub foo ($n) { $n + 1}
&foo
> &foo.defined
True
> &foo = Nil
Cannot modify an immutable Sub (&foo)
in block <unit> at <unknown file> line 1
那么赋值和绑定(bind)有什么区别呢?
如何取消定义变量?

最佳答案

这里有很多不同的问题要讨论。

> my $k := 5;
> $k := Nil;
Cannot use bind operator
第一个问题是 Raku REPL。参见你的最后一个 SO。你试过了吗 CommaIDErepl.it ?
您的代码完全有效:
my $k := 5;
$k := Nil;
say $k; # Nil

继续:
my $k := 5;
$k = Nil;
Cannot assign to an immutable value
这是不同的。绑定(bind)后 5$k , $k = Nil代码试图将一个值赋给一个数字。仅限容器 [1] 支持任务。数字不是容器,因此您无法分配给它。

澄清一些你提到但没有明确涵盖的情况:
my @foo;
@foo := Nil;
Type check failed in binding; expected Positional...
虽然标量变量(带有 $ 符号的变量)将绑定(bind)到任何值或容器,但 @标记变量只会绑定(bind)到 Positional容器,例如 Array . (同样,从 %Associative,例如 Hash。)
不仅如此,这些容器总是被定义的。所以他们仍然返回 True.defined即使它们是空的:
my @foo := Array.new; # An empty array
say @foo.elems; # 0 -- zero elements
say @foo.defined; # True -- despite array being empty
正在分配 Nil到一个数组:
my @foo;
@foo = Nil;
say @foo; # [(Any)]
如果声明 @标记变量不会将其绑定(bind)到某些显式 Positional键入它改为绑定(bind)到 @ 的默认选择多变的。这是一个 Array默认元素值为 Any . @foo = Nil;上面的语句分配了一个 Nil value 到 @foo 的第一个元素.将值分配给多元素容器的不存在元素意味着新的 Scalar容器弹出并在分配继续之前绑定(bind)到那个缺失的元素。然后,因为我们要分配一个 Nil ,并且因为 Nil表示没有值, Array的默认值 ( (Any) ) 被复制到 Scalar而不是 Nil .

转到 sub案件...
sub foo {}
&foo = {} # Cannot modify an immutable Sub (&foo)
&foo := {} # Cannot use bind operator ...
而一个 sub foo声明生成 &foo标识符,它故意既不可分配也不可绑定(bind)。如果你想要一个 Callable变量,您必须使用普通变量声明来声明一个。

Unbind or undefine a variable


你不能解除变量的绑定(bind),让它们根本不绑定(bind)任何东西。 (换句话说,Raku 避免使用 the billion dollar mistake 。)在某些情况下,您可以重新绑定(bind)变量。
在某些情况下,您可以将未定义的值绑定(bind)或分配给变量。如果它不是标量变量,那么就像 @上面提到的变量示例。接下来考虑标量情况。
绑定(bind)案例的一个例子:
my $foo := Any;
say $foo.defined; # False
say $foo; # (Any)
say $foo.VAR.WHAT; # (Any)
我们来看看 .VAR马上就要了。
委托(delegate)案例:
my $foo = Any;
say $foo.defined; # False
say $foo.WHAT; # (Any)
say $foo.VAR.WHAT; # (Scalar)
重要的是要了解在这种情况下 $foo绑定(bind)到 Scalar ,这是一个容器,最明确地“定义”,对于“定义”的某些定义,尽管在 say $foo.defined; 中出现相反的情况线。
say $foo.WHAT;Scalar仍然隐藏。相反,我们看到一个 (Any) .但是 (Any)Scalar 中保存的值的类型容器绑定(bind)到 $foo .
在下一行中,我们通过拨打 .VAR.WHAT 开始揭开面纱。在 $foo . .VAR获取 Scalar展示自己,而不是产生它所包含的值(value)。所以我们看到类型 Scalar .
但是如果你拨打 .defined在那 Scalar它仍然坚持隐藏!:
my $foo;
say $foo.VAR.defined; # False
say $foo.VAR.DEFINITE; # True
(迫使 Raku 告诉你关于其确定性观点的最终真相的唯一方法是调用确定性的最终仲裁者, .DEFINITE。)
那么规则是什么?
如果根据原始变量声明这样做是有效的,编译器将允许您将给定的新值或容器分配或绑定(bind)到变量。
分配或绑定(bind)未定义的值遵循相同的规则。
捆绑
所有变量都必须在其声明的末尾绑定(bind)。
如果变量的声明允许将未定义的值绑定(bind)/分配给该变量,则该变量在这个意义上可以是未定义的。但在所有其他情况下和感官变量本身永远不能“未绑定(bind)”或“未定义”。
绑定(bind)是关于使变量对应于某个容器或值:
  • 带有 @ 的变量和 % sigils 必须绑定(bind)到容器(分别默认为 ArrayHash)。
  • 带有 $ 的变量sigil 必须绑定(bind)到容器(默认 Scalar )或值。
  • 带有 & 的变量印记必须绑定(bind)到 Callable值或 Scalar限制为包含 Callable值(value)。 (作为声明 & 的结果可见的 sub 标记变量不允许重新绑定(bind)或赋值。)

  • 任务
    赋值意味着将值复制到容器中。
    如果一个变量绑定(bind)到一个容器,那么你可以赋值给它,前提是编译器根据原始变量声明允许赋值。
    如果变量未绑定(bind)到容器,则编译器将拒绝对其进行赋值。
    标量变量
    如果您将标量容器当作一个值来使用,那么您将获得容器内保存的值。
    将值(已定义或未定义)绑定(bind)到标量变量将意味着它将停止充当容器。如果您然后尝试分配给该变量,它将不起作用。您需要将其重新绑定(bind)回容器。
    脚注
    [1] 在这个答案中,我使用了“容器”这个词来指代任何可以作为包含其他值的容器的值。例如, Array 的实例, Hash , 或 Scalar .

    关于raku - 在 raku 中取消绑定(bind)或取消定义变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64485449/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com