假设我有一个具有多个属性的类,但我只需要其中一些来构建对象;其余属性的值取决于这些公共(public)属性。但是,我仍然想使用以属性命名的方法来访问其余属性的值。从我的脑海中,有两个选择:
第一个选项:
new
方法。或留下new
方法,而是使用 BUILD
子方法将传递的参数设置为正确的属性并使用此参数的值设置剩余的属性。 class Foo {
has Int $.a;
has Int $.b;
has Int $.c;
submethod BUILD(:$!a) {
$!b = $!a ** 2;
$!c = $!a ** 3;
}
}
say Foo.new(:2a, :1b); #=> Foo.new(a => 2, b => 4, c => 8)
say Foo.new(:2a, :1b).b; #=> 8
第二种选择:
用
$.
声明仅对象构造所需的那些属性,并使用 $!
修改剩余的属性(用 TWEAK
声明)对象构造后的子方法。但是,现在我需要为这些属性创建访问器方法。class Bar {
has Int $.a;
has Int $!b;
has Int $!c;
submethod TWEAK {
$!b = $!a ** 2;
$!c = $!a ** 3;
}
method b { $!b }
method c { $!c }
}
say Bar.new(:2a, :1b); #=> Bar.new(a => 2)
say Bar.new(:2a, :1b).b; #=> 8
问题
最好的选择是什么?还有其他选择吗?每个选项的优点/缺点是什么?
最佳答案
就我个人而言,我会很简单:
class Foo {
has Int $.a;
has Int $!b = $!a ** 2;
has Int $!c = $!a ** 3;
method b { $!b }
method c { $!c }
}
say Foo.new(:2a, :1b); #=> Foo.new(a => 2)
say Foo.new(:2a, :1b).b; #=> 4
只需使用属性的默认构造函数和默认值,并添加几个基本的读取方法。默认构造函数只更新公共(public)属性,所以如果你尝试覆盖
b
或 c
这被忽略了。如果您愿意,可以添加
BUILD
如果有人尝试并设置它们,子方法会出错。在这个案例(可能是最终用例)的评论中提出了一个很好的观点:
class Foo {
has Int $.a;
method b() is pure { $!a ** 2 }
method c() is pure { $!a ** 3 }
}
say Foo.new(:2a, :1b); #=> Foo.new(a => 2)
say Foo.new(:2a, :1b).b; #=> 4
根据计算的复杂性,您可能希望使用
is cached
特质也。
关于class - 使用自动生成的公共(public)属性方法与创建访问私有(private)属性的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59568073/