はじめまして。
今月からRoxxな人になった前田といいます。
よろしくおねがいします。
PHPでは...
というキーワードがあります。
以下、例です。
<?php // 可変長引数 function printArgs(...$inputs) { echo $inputs[0]; // apple echo $inputs[1]; // banana echo $inputs[2]; // chocolate } printArgs('apple', 'banana', 'chocolate');
<?php // 引数のアンパック function printArgs($a, $b, $c) { // 略 } $args = ['aaple', 'banana', 'chocolate']; printArgs(...$args);
前から存在は知っていたのですが、わりと自分の中ではただのトリビアになっていて、あまり使用してきませんでした。
というより使用する場面をいまいち把握できていませんでした。
最近、個人で開発しているときに「あれ、意外と...
は便利なのでは!?」となったので紹介します。
事例
以下の仕様のクラスを考えます。
- ユーザ定義クラスStatusがある
- Statusを複数まとめて扱うクラスがほしい
- つまり、配列をラップしたクラス
- 以下の要件を備える
...
をつかわない場合
以下のようになると思います。
<?php class StatusCollection { /** @var Status[] */ private $items; public function __construct(array $items) { foreach ($items as $item) { if (!$item instanceof Status) { throw new InvalidArgumentException(); } } $this->items = array_values($items); } } $items = [Status::on(), Statuss::off(), Status::unknown()]; $statuses = new StatusCollection($items);
ポイントとしては、Status以外の要素がある場合は例外を投げていること、 array_values
でキーを振り直しているところです。
こういったバリデーションに近い部分にコードを多く使うと読みづらいですね。
こういった読みづらさを...
を使うと解消できます。
array_valuesを取り除く
まず array_values
を消していきます。
<?php class StatusCollection { /** @var Status[] */ private $items; public function __construct(...$items) { foreach ($items as $item) { if (!$item instanceof Status) { throw new InvalidArgumentException(); } } $this->items = $items; } } $items = [Status::on(), Statuss::off(), Status::unknown()]; $statuses = new StatusCollection(...$items);
コンストラクタの仮引数を ...
に変更しました。
これにより、キーの採番はPHPが勝手に行うようになるので、array_values
が不要になります。
また、仮引数を可変長引数にしたので、実引数も忘れずに...
でアンパックします。
型チェックのコードを取り除く
次に一番面積をとっているforeach
を消していきます。
<?php class StatusCollection { /** @var Status[] */ private $items; public function __construct(Status ...$items) { $this->items = $items; } } $items = [Status::on(), Statuss::off(), Status::unknown()]; $statuses = new StatusCollection(...$items);
単純に型宣言(タイプヒント)を使用しています。
...
を使う前は配列を受け取っていたのでarray
で指定していましたが、...
を使うことで配列の要素の型を指定できます。
面積をとっていたforeach
を削除できたので、とても見通しの良いコードになりました。
まとめ
...
を使用することで、配列のキーを気にしなくて済む...
を使用することで、配列の要素の型を指定できる
...
は型宣言とセットで使用することでパワーを発揮しそうです。
「連想配列じゃなくてもいいんだけど・・・」という場合も結構あるので、配列のキーを気にしなくて良い場合は積極的に使っていこうと思います。