[英]Php, can "readonly" replace protected get-ters?
before Php 8.1 we could wrote that:在 Php 8.1 之前我们可以这样写:
abstract class Base
{
private $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
protected function getThing()
{
return $this->thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->getThing();
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->getThing();
}
}
so getThing()
was to get the inner thing
object. It could have been written like that:所以
getThing()
是为了得到里面的thing
object。它可以这样写:
abstract class Base
{
protected $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->thing;
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->thing;
}
}
it's shorter, does the same, but not $thing
isn't really protected, it can be read and modified (the first example at least prevented from modifing).它更短,功能相同,但
$thing
并没有真正受到保护,它可以被读取和修改(第一个示例至少可以防止修改)。 But here comes the readonly
modifier:但是这里出现了
readonly
修饰符:
abstract class Base
{
readonly private $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
protected function getThing()
{
return $this->thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->thing;
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->thing;
}
}
I think this is a serious game changer, makes a lot of getters futile.我认为这是一个严重的游戏规则改变者,让很多 getters 变得徒劳。 Of course it looks you're reaching a tag variable, but still acts like a method, once it was written (in constructor) and now no longer possible to overwrite.
当然看起来你正在访问一个标记变量,但它仍然像一个方法一样,一旦它被写入(在构造函数中)并且现在不再可能被覆盖。
So, can "readonly" replace protected get-ters?那么,“readonly”能否取代受保护的 getter 呢?
You're almost there.你快到了。 The
readonly
modifier doesn't add any visibility, so you still need to declare the property protected
: readonly
修饰符不添加任何可见性,因此您仍然需要声明属性protected
:
abstract class Base
{
readonly protected $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->thing;
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->thing;
}
}
This will then work for your specific use case .这将适用于您的特定用例。 The RFC where the feature was proposed used an example of a public getter being replaced by a public
readonly
property, which is exactly the same principle: the property can now have the visibility that the getter used to have.提出该功能的 RFC使用了一个公共getter 被公共
readonly
属性替换的示例,这与原则完全相同:该属性现在可以具有 getter 曾经具有的可见性。
It's important to note that this is not a universal replacement for getters though - in the original code, the base class could write to the property as many times as it liked, but the readonly
keyword means "write only once".重要的是要注意,尽管这不是getter 的通用替代品 - 在原始代码中,基数 class可以根据需要多次写入该属性,但
readonly
关键字表示“只写一次”。 For instance, you might have a counter that is incremented by a particular method in the base class, and want child classes to read it but not write it:例如,您可能有一个计数器,该计数器由基 class 中的特定方法递增,并且希望子类读取它但不写入它:
abstract class Base
{
private int $counter = 0;
protected function getCounter(): int {
return $this->counter;
}
public function doSomething(): void {
// ...
$this->counter++;
// ...
}
}
class Test1 extends Base
{
private function needCounter()
{
// ...
$counter = $this->getCounter();
// ...
}
}
Here, readonly
is not useful, because it would forbid the $this->counter++
statement in the base class. There is currently a proposal for "asymmetric visibility" , which would cater for this use case - you would be able to say that the variable was "private for writing, but protected for reading".在这里,
readonly
没有用,因为它会禁止 base class 中的$this->counter++
语句。目前有一个针对“不对称可见性”的提议,它可以满足这种用例 - 你可以说变量是“私有的,但受保护的”。 If this passes, the earliest it will be introduced is in PHP 8.3, at the end of 2023.如果通过,最早将在 PHP 8.3 中引入,即 2023 年底。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.