如何在 Perl 6 中制作对象的单独副本?

How to make a separate copy of an object in Perl 6?

我不是很明白the docs,所以我尝试了clone,好像有一个可变的属性class,它可以在使用旧对象的新对象(这是我不想要的)。如何使它们(即副本和原件)完全分开?

class A {
  has @.a;
}

my A $x = A.new;
my A $y = A.new;

$x.a = 1, 2;

$y = $x.clone;

$x.a.push(4);
say $y.a; # [1 2 4]

Mu 继承的默认值 clone 很浅,如文档所述。这意味着它只会复制对象本身,而不是对象引用的任何内容。可以覆盖 clone 以获得您喜欢的语义,这可能是最好的做法。

在执行此操作时需要知道的一件有用的事情是 clone 采用命名参数并使用它们分配给克隆对象的属性。这是值得了解的,因为:

  • 在覆盖 clone 时应确保处理此问题,以避免使用此功能的被覆盖 clone 方法的用户感到意外
  • 可以在覆盖 clone 时使用它来简洁地选择克隆特定数组或散列属性

因此对于问题中的情况,写作:

class A {
    has @.a;
    method clone() {
        callwith(:@!a, |%_)
    }
}

将产生可能需要的输出 [1 2]。它是如何工作的?

  • |%_ 只是将任何调整传递给此 clone 指定方法的调用者
  • :@!aa => @!a
  • 的缩写
  • callwith 调用继承的 clone(在本例中来自 Mu
  • 目标对象中的 @!a 使用赋值,而不是绑定,语义(就像在对象构造期间一样),导致数组的副本

此快捷方式也适用于散列属性。对于包含另一个对象的属性,它看起来像 callsame(x => $!x.clone).