【问题标题】:Using public and private methods inside their class in Perl 6在 Perl 6 的类中使用公共和私有方法
【发布时间】:2018-04-22 20:40:06
【问题描述】:

如果我有一个公共方法,我可以在其类中使用$.nameself.name 调用它:

class TEST {
  has Int $.a;

  method b($x) {
    return $!a * $x;
  }

  method c($y) {
    return self.b($y) * 3; # or $.b($y)
  }
}

my $m = TEST.new(a => 10);
say $m.c(2); # 60

但是如果我将b设为私有方法,我只能用self!b调用它,而不是$!b,否则我会收到以下错误消息:

Attribute $!b not declared in class TEST

这条规则的背后是什么?在自己的类中调用方法的规则是什么?

【问题讨论】:

  • 我认为以下是正确的。我希望它会有所帮助。 $!bar$!baz 等总是指私有属性。总是。即使文档另有说明,属性始终是私有的。 foo!bar!bar always 指的是私有方法,而不是属性(尽管他们的代码可以)。 foo.bar.bar always 指的是公共方法。 从不 编写foo.bar(...).bar(...) 以使用公共访问器获取或设置私有属性的值;而是只写foo.bar.bar 来读取,foo.bar = ....bar = 来获取或设置foo$!bar 属性的值。
  • 如果您需要一个可以设置私有属性的公共访问器,请确保在属性声明中添加is rw

标签: raku


【解决方案1】:

一个属性在一个类中总是可以被称为$!foo。如果您这样做,则将生成代码以直接访问属性本身,并且任何继承您的类的类将能够更改此行为。

如果你在一个类的声明中使用has $.foo,这意味着一个公共访问器(如果你添加is rw,它也可以作为一个mutator。

当您在代码中使用$.foo 时,它完全$( self.foo ) 相同。这意味着它将在self 上调用foo 方法,并逐项列出返回值(如果还没有的话,让它成为一个单一的“事物”)。如果您使用$!foo 定义属性并且您自己没有提供method foo,这将出错。

这更进一步:$.bar 真正的意思是self.bar:你只需要有一个名为bar 的方法,它可能与任何属性都没有关系。

如果你定义了一个私有方法!baz!只是表示该方法的隐私,这意味着你需要将它调用为self!baz。它有 no 短语法。

我个人不喜欢你可以说$.zippo,即使zippo 不是一个属性。但恐怕那艘船已经航行了。但是这种行为现在让您感到困惑:-(

那么,在调用私有方法时没有简短语法的规则背后是什么?不确定,我猜$!foo 确实已经被认为是直接访问该属性,如果该属性不存在,则会为您提供编译时错误。

希望这能回答你的问题!

【讨论】:

  • $.foo 实际上与self.foo 不同,它是$(self.foo) - 也就是说,它逐项列出了结果。
  • 我已更新 LIz 的答案以包含标量上下文。
  • “逐项”是什么意思?你能举个例子吗?
  • Jonathan++,我今天学到了一些东西 :-) “项目化”是使 Iterable 不可迭代的过程。例如,如果我们有my @a = ^5; sub foo(*@b) { dd @b };,而你有foo @a,你会得到[0, 1, 2, 3, 4](一个有5个元素的数组),而如果你通过调用.item方法来逐项列出数组,比如foo @a.item,你会得到[[0, 1, 2, 3, 4],](所以是一个有 1 个元素的数组)。您也可以在 $ 前添加前缀:foo $@a
  • 谢谢!我希望,现在我能更好地理解它了。
猜你喜欢
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 2014-08-06
  • 2014-02-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
相关资源
最近更新 更多