krak/adt

PHP 中的代数数据类型

v0.1.1 2019-09-15 04:37 UTC

This package is auto-updated.

Last update: 2024-09-15 15:05:53 UTC


README

PHP 中代数数据类型的穷举实现。

在其他语言如 Swift 或 Rust 中也称为带有相关值的枚举。

安装

使用 composer 在 krak/adt 中安装

使用方法

<?php

use Krak\ADT\ADT;

/**
 * @method static Upc upc(int $numberSystem, int $manufacturer, int $product, int $check)
 * @method static QrCode qrCode(string $productCode)
 */
abstract class Barcode extends ADT {
    public static function types(): array {
        return [Upc::class, QrCode::class];
    }
}

final class Upc extends Barcode {
    public $numberSystem;
    public $manufacturer;
    public $product;
    public $check;

    public function __construct(int $numberSystem, int $manufacturer, int $product, int $check) {
        $this->numberSystem = $numberSystem;
        $this->manufacturer = $manufacturer;
        $this->product = $product;
        $this->check = $check;
    }
}

final class QrCode extends Barcode {
    public $productCode;

    public function __construct(string $productCode) {
        $this->productCode = $productCode;
    }
}

$barcode = new QrCode('abc123');

// requires that all cases are set or exception is thrown
$oneOrTwo = $barcode->match([
    Upc::class => function(Upc $upc) { return 1;},
    QrCode::class => function(QrCode $qrCode) { return 2; },
]);

// allow a default value
$oneOrNull = $barcode->matchWithDefault([
    Upc::class => function(Upc $upc) { return 1; }
]);

// return static values
$threeOrFour = $barcode->match([
    Upc::class => 3,
    QrCode::class => 4,
]);

// static constructors
$qrCode = Barcode::qrCode('abc123');

自动加载问题

使用上面的示例,如果你在引用 Barcode 类之前尝试创建 QrCode 或 Upc,使用 composer 的 psr-4 自动加载器时可能会遇到文件未找到的错误。

有几种方法可以解决这个问题

  1. 使用类映射

  2. 在 composer 自动加载文件部分包含枚举类文件(例如,php-inc 可以使这更容易)

  3. 使用基础 ADT 类提供的静态构造函数

    <?php
    
    $upc = Barcode::upc(1, 2, 3, 4);
    $qrCode = Barcode::qrCode('abc123');

测试

测试通过 make test 运行,并存储在 test 目录中。我们使用 peridot 进行测试。