clone - 如何在 Perl 6 中创建对象的单独副本?

标签 clone deep-copy raku 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]

最佳答案

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

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

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

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

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

将产生预期的输出[1 2]。它是如何工作的?

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

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

关于clone - 如何在 Perl 6 中创建对象的单独副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50069947/

相关文章:

python - 是否存在无法创建深拷贝的对象?

swift - 具有包含数组的元素的数组的深拷贝?

module - 检查可选模块可用性的最佳方法

concurrency - 点击 IO::Notifications 时出现错误 "emit without supply or react"

jquery 克隆元素并在对原始元素进行更改后追加它

Java 实现克隆、泛型类。

c# - 原始列表的浅克隆列表中的项目被清除会发生什么

git - 通过 http 访问本地 git repo

cocoa - 字典的深层复制在 Xcode 4.2 中给出分析错误

perl - 是否可以有两个不同的 Perl 版本?