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

时间:2018-04-27 20:36:33

标签: clone deep-copy perl6 shallow-copy

我不完全理解the docs,所以我尝试了clone,似乎有一个可变类的属性,它可以在旧对象中使用旧的更改一个(这就是我不想要的)。如何使它们(即副本和原件)完全分开?

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]

1 个答案:

答案 0 :(得分:9)

clone继承的默认Mu很浅,如文档所述。这意味着它只会复制对象本身,而不会复制对象引用的任何内容。可以覆盖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)