da2e / generic-collection
基于PHP的泛型集合实现
v1.3.0
2020-01-10 12:26 UTC
Requires
- php: >=7.1
Requires (Dev)
- ext-curl: *
- phpunit/phpunit: ^7.5
This package is not auto-updated.
Last update: 2024-09-14 11:28:17 UTC
README
这个小型库提供了基于PHP的泛型集合实现。
PHP缺乏泛型(与Java、C++等相反)。问题是您无法控制和确保数组/集合/哈希等元素实现了哪些类型。
示例
$a = [1, 2, new \stdClass(), function () { return 'foo'; }]; $r = 0; foreach ($a as $v) { $r += $v; // here for stdClass and a closure you will get an error: Object of class ... could not be converted to int. }
例如,在Java中,您可以通过泛型来消除这个问题
List<String> v = new ArrayList<String>();
这个库提供了一个面向对象的解决方案,以便在集合/数组中拥有同质类型。
内置类型
- DA2E\GenericCollection\Type\ArrayType(对应PHP内置的is_array()函数)。
- DA2E\GenericCollection\Type\BoolType(对应PHP内置的is_bool()函数)。
- DA2E\GenericCollection\Type\CallableType(对应PHP内置的is_callable()函数)。
- DA2E\GenericCollection\Type\FloatType(对应PHP内置的is_float()函数)。
- DA2E\GenericCollection\Type\IntType(对应PHP内置的is_int()函数)。
- DA2E\GenericCollection\Type\IterableType(对应PHP内置的is_iterable()函数)。
- DA2E\GenericCollection\Type\MixedType(通过任何值传递)。
- DA2E\GenericCollection\Type\NullType(对应PHP内置的is_null()函数)。
- DA2E\GenericCollection\Type\NumericType(对应PHP内置的is_numeric()函数)。
- DA2E\GenericCollection\Type\ObjectType(对应PHP内置的is_object()函数)。
- DA2E\GenericCollection\Type\ResourceType(对应PHP内置的is_resource()函数)。
- DA2E\GenericCollection\Type\ScalarType(对应PHP内置的is_scalar()函数)。
- DA2E\GenericCollection\Type\StringType(对应PHP内置的is_string()函数)。
特殊类型
- DA2E\GenericCollection\Type\CustomType:接受一个带有单个参数的回调函数来构建自定义验证器。例如:
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\CustomType; $collection = new GCollection(new CustomType(function ($value) { return $value === 'foobar'; })); $collection[] = 'foobar'; // valid $collection[] = 'bar'; // invalid
- DA2E\GenericCollection\Type\GCollectionType:嵌套GCollections的类型。例如:
use DA2E\GenericCollection\Type\GCollectionType; use DA2E\GenericCollection\Type\StringType; use DA2E\GenericCollection\GCollection; $collection = new GCollection(new GCollectionType()); $collection[] = new GCollection(new StringType()); // valid $collection[] = new StringType(); // invalid
ObjectType
ObjectType可以选择接受一个完全限定的类名来验证该值是否实现了给定的类。例如:
$value = new Some\Class\Here(); $type = new DA2E\GenericCollection\Type\ObjectType('Some\Class\Here'); $type->validate($value);
如何使用
- 创建一个泛型集合。
- 在构造函数中传递该集合的类型。
- 泛型集合实现了\ArrayAccess接口,因此只需将/推入元素到数组。
- 在向集合添加元素时,会立即对给定类型进行验证。
- 如果类型无效,将抛出DA2E\GenericCollection\Exception\InvalidTypeException。
示例
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; use DA2E\GenericCollection\Exception\InvalidTypeException; try { $collection = new GCollection(new StringType()); // You can pass an array as 2nd argument as well. $collection[] = 'string'; // this one is fine $collection[] = 1; // this one will throw an exception } catch (InvalidTypeException $e) { // handle exception }
- 如果您将集合作为参数传递给方法/函数,则可以要求所有元素都应实现确切的类型
function foobar(GCollection $collection) { try { $collection->elementsShouldBeTypeOf(StringType::class); // If something is wrong InvalidTypeException is thrown } catch (InvalidTypeException $e) { // handle exception } // ... }
如果集合包含对象,则还可以进一步确保元素是特定类的实例。
function foobar(GCollection $collection) { try { $collection->elementsShouldBeTypeOf(ObjectType::class); // This is fine and valid but does not give a lot of information which exactly object is there. $collection->elementsShouldBeTypeOf(YourAnyClass::class); // This is more verbose and clear. We know that we expect a concrete YourAnyClass objects. } catch (InvalidTypeException $e) { // handle exception } // ... }
GCollectionInterface的附加功能
GCollectionInterface中有许多附加功能(例如map、filter、slice、shuffle等)。请参阅接口以查看所有功能。
map
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; $collection = new GCollection(new StringType(), ['a' ,'b']); $collection->map(function ($item) { return $item . '2'; }); // Returns [ 'a2', 'b2', 'c2' ]
filter
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; $collection = new GCollection(new StringType(), ['a' ,'b']); $collection->filter(function ($item) { return $item === 'b'; }); // Returns [ 'b' ]
sort
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; $collection = new GCollection(new StringType(), ['a' ,'b']); $collection->sort(function (array $items) { rsort($items); // Here you can call any sort function you wish. return $items; }); // Returns [ 'b', 'a' ]