(jp) =
<!–
–>

非対称可視性と呼ばれる新しい RFC が街にあり、その目的は、次のことができるプロパティを定義することです。 に書かれた 保護されたスコープまたはプライベート スコープから、ただし外部 (パブリック スコープ) からは、 読んだ.
次のようになります。
final class Post
public function __construct(
public private(set) string $title,
)
ここでは、いくつかのことが行われています。
- 昇格したプロパティを使用してタイトルを定義しています。 と
- 私たちはそれを明確に言っています
$title内でのみ設定 (したがって上書き) できます。privateの範囲Post.
つまり、次のことが許可されます。
final class Post
public function __construct(
public private(set) string $title,
)
public function changeTitle(string $title): void
if (strlen($title) < 30)
throw new InvalidTitle('Title length should be at least 30');
$this->title = $title;
これはそうではありませんが:
$post = new Post('Title');
$post->title = 'Another title';
私はそれがかなりまともな提案だと思います.オブジェクトのプロパティへのパブリック読み取り専用アクセスが必要なユースケースをたくさん思いつくことができます(ゲッターを実装するオーバーヘッドなしで)。クラス。 そのクラスは、たとえば、内部チェックを追加して、値が任意の数のビジネス ルールに準拠していることを確認できます。簡単な例として、投稿のタイトルが少なくとも 30 文字の長さであることを確認します。
RFC が通過することを願っています。
右?
さて、私はそれに問題があります。 実際、RFCではありません 自体 ――とてもいい提案だと思います。 いいえ、私の懸念はこの RFC 自体ではなく、読み取り専用プロパティとの密接な関係にあります。
ここでは、スコープが読み取り専用プロパティと重複する (完全に同じではありませんが) RFC があり、将来的には読み取り専用プロパティを完全に置き換える可能性があります。 以下は RFC からの引用です。
現時点では、スコープを設定できる操作は、読み取りと書き込みの 2 つだけです。 概念的には、独自の可視性コントロールを使用して追加の操作を追加できます。 考えられる例は次のとおりです。
- …
- once – プロパティを一度だけ設定し、その後凍結することを許可します。 この場合、 public private(once) は readonly とまったく同じです一方、 public protected(once) は似ていますが、プロパティを子クラスから設定することもできます。
この RFC とその後継が読み取り専用プロパティを完全に置き換える可能性があることは明らかです。 読み取り専用プロパティ — PHP 8.1 で 1 年前に追加されたばかりの機能であり、今年後半に PHP 8.2 に追加される読み取り専用クラスは言うまでもありません。
非対称の可視性は素晴らしい提案ですが、私が恐れているのは、機能を追加して 3 ~ 4 年後に機能を無意味なものにするだけの場合、PHP がどうなるかということです。 PHP をどのように変更するかについては、非常に慎重かつ慎重に検討する必要があり、既存の機能をすぐに却下してはなりません。
もしそうなら、私たちはコミュニティ内の多くの不確実性と不安定性に貢献するでしょう. 誰かが今日読み取り専用プロパティを採用していて、1 年後に PHP 9.0 までに非推奨になり、非対称可視性が優先されると聞いた場合を想像してみてください。
読み取り専用プロパティが維持され、非対称の可視性と共存する場合でも、混乱の余地が非常に多くなります。いつ読み取り専用プロパティを使用できるのでしょうか。 代わりに常に非対称の可視性を使用する必要がありますか? 言語がこの種の質問や疑問を受け入れる余地を許すなら、言語設計は悪いと思います。
さらに、私はこの問題に関するマルコの意見に完全に同意します。
読み取り専用プロパティを積極的に使用し、状態を可能な限り不変にしようとしています。
の中に 非常に まれなケース
[…]public getとprivate setとにかく非常に状況に応じたものになりつつある従来のゲッターとセッターに依存していますが、それでも完全に正常に動作します。実際、私が最近書いているゲッターとセッターは非常に少ないので、リフレクションが改善されていなくても、ゲッターとセッターのセマンティクスが言語、特にミュータブルな言語に忍び込む必要がある理由がわかりません。
明確にするために、非対称の可視性と読み取り専用プロパティが同じではないことをよく知っています。 非対称の可視性は、はるかに広い範囲をカバーし、より高い柔軟性を提供します。 ただし、ニキータは昨年、非対称可視性に非常によく似たアイデアをすでに生み出していますが、これは読み取り専用プロパティを優先して追求されたものではありません。 私たちが望むかどうかについての議論 柔軟性の向上 はすでに行われており、当時の結論は次のとおりでした。 readonly プロパティはユース ケースの 95% をカバーしており、それで十分です。
PHP が、柔軟性をもう少し高めるために、数年ごとにコア機能を捨てる言語になるのを見るのは悲しいことです。 この場合にもっと柔軟性が必要な場合は、2 年前に読み取り専用プロパティが詳細に議論されたときに決定する必要がありました。 今は — 私の意見では — 手遅れです。
最後に、オブジェクトを新しい値で複製することについて心配している場合 (この RFC で解決できる問題であり、読み取り専用プロパティでは解決できない問題です): 人々は既に、複製中に読み取り専用プロパティを書き換えることができる何らかの構文に取り組んでいます。 まったく別のアプローチを思いつくよりも、そこに注力したほうがいいと思います。
さらに言えば、より多くの機能を可能にする (ビジネス ルールを内部的に保護する) 非対称の可視性で示した元の例は、完全には正しくありませんでした。 同じ は それらを複製するときに読み取り専用の値を上書きする方法があることを考えると、読み取り専用のプロパティで可能です。
final class Post
public function __construct(
public readonly string $title,
)
public function changeTitle(string $title): self
if (strlen($title) < 30)
throw new InvalidTitle('Title length should be at least 30');
return clone $this with
title: $title,
ああ、上記の構文はまだ利用できませんが、いくつかの追加のユーザーランド コードを使用して、今日のクローン作成中に読み取り専用プロパティを上書きすることは既に可能です。
final class Post
use Cloneable;
public function __construct(
public readonly string $title,
)
public function changeTitle(string $title): self
if (strlen($title) < 30)
throw new InvalidTitle('Title length should be at least 30');
return $this->with(
title: $title,
);
要約すると、非対称の可視性は優れた機能だと思います いくつか ユースケースですが、代替手段もあります。 全体として、読み取り専用のプロパティを使用できるようになった今、非対称の可視性を追加する価値はないと思います。 読み取り専用のプロパティを決定しました。ユーザーのために、あいまいな機能が混乱するのを防ぐために、それらに固執する必要があります。
おもう 最近、PHP の統一されたビジョンと方向性が欠けていますであり、この RFC は、それ自体が優れているため、実践に欠けていることの良い例です。 私たち (つまり PHP の内部関係者) が解決策を見つけられることを願っています。将来、PHP Foundation がこれらすべてにおいて重要な役割を果たすのではないでしょうか?
//platform.twitter.com/widgets.js