【サルが書く】PHP8のunion typesとmixedについて考える
わあきゃあ!
PHP8がついにリリースされましたね!
そこで気になった新機能であるUnionTypesとmixed型についてまとめてみました。
1. UnionTypes
PHP8以前はプロパティ、パラメーター、および戻り値の型に対して単一の型しか宣言できませんでした。
またPHP7.1以降のバージョンではnull許容型があります。
PHP8以前は限定的なUnionTypesしかできませんでした。
ちなみにnull許容で書く場合は型の前に?をつけることでできます。 例) ?string
PHP8以前ではPHPDocを使用してのUnionTypesはありました。
class Test {
/**
* @var int|float
*/
private $test;
/**
* @param int|float $foo
* @return int|float
*/
public function square(int $foo): int {
return $foo * $foo;
}
}
PHP8ではこのように書けるってことですね!
この場合はPHPDocは書くべきなんですかね?
@param
と@return
の型についてのPHPDocはいらなくて、メソッドについての説明だけは残すって感じですかね?
class Test {
private int|float $test;
public function square(int|float $foo): int|float {
return $foo * $foo;
}
}
voidの扱いについて
voidはUnionTypesでは使用できません。
なので以下のような指定はできません。
strign|void
null許容型について
UnionTypesとnull許容型についてですが
?int|float
のようには書けず、int|float|null
のように書きます。
型の重複について
int|float|INT
のように型は重複して書くことはできません。
false疑似型
falseリテラルの型が、UnionTypesの一部としてサポートされています。
これは内部関数の多くが、失敗時にnullではなくfalseを返すために実装されています。
またこれは単独で使用することはできません。
なので、false
, ?false
, false|null
のようなものは使用できません。
union型と型強制
strict_typesが有効でない場合、スカラー値は暗黙の型変換の対象となります。
例えば bool|int
に対して"0"
が渡ったときにはfalse
と0
が暗黙の型変換の対象になります。
型変換の優先順位は以下のようになっているので、優先順位1のintへの型変換が働き"0"
は0
へ変換されます。
型変換の優先順位
1.int 2.float 3.string 4.bool
2. mixed型
mixed型は以下のunion型と一緒です。
array|bool|callable|int|float|object|resource|string|null
最初こんな型があっても宣言しないのと同じじゃんとは考えていましたが、もちろん導入されたのには理由があります。
理由についてはこちらの記事 で詳しく書いてあるので、ユーザー目線からの意見をまとめました。
メリット
- mixedと宣言することで、ここはすべての型が入りうるということを注意喚起できる
- すべての場合で型宣言ができるので統一感のあるコードを書くことができる
- 静的解析がやりやすくなる
- 型指定へのハードルが下がる
- リファクタリングの際にmixedをつければ検収済みだというマークになる
デメリット
- あまり型宣言に精通していない人がコード書いた場合にTypeScriptのanyのように乱用される可能性がある
mixed型まとめ
メリットもデメリットもありますが、個人的にはmixed乱用はかなり有り得そうな話だと思っています。なので型宣言を適切に行えている前提かつ、miexdを乱用しなくても良い設計を心が得ける必要は出てきそうですね。
参考文献
Discussion