kphp
kphp copied to clipboard
Universal `cast<T>` function
Depends on #764.
Problem
Given there are two ways to cast a variable to some type:
- For primitive types there's
(T)$v, whereTis a primitive type. - For class instances there's
instance_cast($o, T::class).
Here we can see that instance-way is fully compatible with generics (you can use class-string type for T::class), but primitives are not, since you can't do ($t)$v (where $t is of type class-string<T>).
Solution
Function cast($v, $t), where $t is known at compile-time and can be
Class::classclass-string<T>- Primitive type string like
'int','string', etc.
Use cases
Given mixed[]. Wanted to cast it to int[], float[], string[] or any other more specific type. Currently it's necessary to make own function for each type:
array_force_int($array): int[]array_force_float($array): float[]array_force_string($array): string[]- ...
All these functions have the same code, only casted type is different:
foreach ($array as $k => $v) {
$typed_array[$k] = (T)$v; // T is int/float/string/etc.
// OR
$typed_array[$k] = instance_cast($v, T); // T is class-string
}
With the cast function it could be just one function array_force($array, $type):
/**
* @kphp-generic In, Out
* @param In[] $array
* @param class-string<Out> $type
*/
function array_force(array $array, $type): array {
foreach ($array as $k => $v) {
$typed_array[$k] = cast($v, $type);
}
}