在 Raku 中克隆对象
Cloning Objects in Raku
在 raku 中克隆对象的最佳方法是什么?我知道存在克隆方法,但它似乎不适用于嵌套对象。
例如,在这个脚本中:
#!/usr/bin/env perl6
class Group {
has Int @!group = Array[Int].new;
method add-item(Int $int) {
@!group.push($int);
}
method print {
say @!group;
}
}
class GroupOfGroups {
has Group @!multi-group = Array[Group].new;
method add-group(Group $group) {
@!multi-group.push($group);
}
method print {
for ^@!multi-group.elems -> $i {
@!multi-group[$i].print;
}
}
}
my $group = Group.new;
$group.add-item(1);
$group.add-item(2);
$group.add-item(3);
my $group-of-groups = GroupOfGroups.new;
$group-of-groups.add-group($group.clone);
$group.add-item(4);
$group.add-item(5);
$group.add-item(6);
$group-of-groups.add-group($group.clone);
$group-of-groups.print;
输出为:
[1 2 3 4 5 6]
[1 2 3 4 5 6]
但我期待它是:
[1 2 3]
[1 2 3 4 5 6]
我不会使用 clone
以外的任何东西来克隆对象。 clone
是由 Mu
定义的原型方法,但在这种情况下由其子类型来实现其行为,因为克隆对象确实克隆了数组属性,但不是以您想要的方式。因此,您可以编写自己的 clone
multis,其行为与您期望的一样:
# Group
multi method clone(::?CLASS:D: --> ::?CLASS:D) {
my ::?CLASS:D $clone .= new;
$clone.add-item: .clone for @!group;
$clone
}
# GroupOfGroups
multi method clone(::?CLASS:D: --> ::?CLASS:D) {
my ::?CLASS:D $clone .= new;
$clone.add-group: .clone for @!multi-group;
$clone
}
::?CLASS
是一个符号,当在 classes 中使用时,它是 class 本身的别名,:D
将类型限制为仅实例.
你好@julio,仔细阅读 docs 让我想到了这个......很有魅力:
method clone { nextwith :foo(@!foo.clone), :bar(%!bar.clone), |%_ }
(这也帮助我理解了深度克隆的“受限”语言帮助背后的合理性)
在 raku 中克隆对象的最佳方法是什么?我知道存在克隆方法,但它似乎不适用于嵌套对象。
例如,在这个脚本中:
#!/usr/bin/env perl6
class Group {
has Int @!group = Array[Int].new;
method add-item(Int $int) {
@!group.push($int);
}
method print {
say @!group;
}
}
class GroupOfGroups {
has Group @!multi-group = Array[Group].new;
method add-group(Group $group) {
@!multi-group.push($group);
}
method print {
for ^@!multi-group.elems -> $i {
@!multi-group[$i].print;
}
}
}
my $group = Group.new;
$group.add-item(1);
$group.add-item(2);
$group.add-item(3);
my $group-of-groups = GroupOfGroups.new;
$group-of-groups.add-group($group.clone);
$group.add-item(4);
$group.add-item(5);
$group.add-item(6);
$group-of-groups.add-group($group.clone);
$group-of-groups.print;
输出为:
[1 2 3 4 5 6]
[1 2 3 4 5 6]
但我期待它是:
[1 2 3]
[1 2 3 4 5 6]
我不会使用 clone
以外的任何东西来克隆对象。 clone
是由 Mu
定义的原型方法,但在这种情况下由其子类型来实现其行为,因为克隆对象确实克隆了数组属性,但不是以您想要的方式。因此,您可以编写自己的 clone
multis,其行为与您期望的一样:
# Group
multi method clone(::?CLASS:D: --> ::?CLASS:D) {
my ::?CLASS:D $clone .= new;
$clone.add-item: .clone for @!group;
$clone
}
# GroupOfGroups
multi method clone(::?CLASS:D: --> ::?CLASS:D) {
my ::?CLASS:D $clone .= new;
$clone.add-group: .clone for @!multi-group;
$clone
}
::?CLASS
是一个符号,当在 classes 中使用时,它是 class 本身的别名,:D
将类型限制为仅实例.
你好@julio,仔细阅读 docs 让我想到了这个......很有魅力:
method clone { nextwith :foo(@!foo.clone), :bar(%!bar.clone), |%_ }
(这也帮助我理解了深度克隆的“受限”语言帮助背后的合理性)