kafkiansky/option

Option:关心你解包的内容。

v0.1.0 2023-07-07 13:29 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:09:38 UTC


README

Option:关心你解包的内容。

需求

  • PHP 8.1 或更高版本。

安装

该包可以通过 composer 安装

composer require kafkiansky/option

动机

我所见过的每一个 Option 模式实现都允许你调用 unwrap 并得到一个值或一个异常,在我看来,这与调用 null 的方法并无不同。同样的行为。同样的生产环境错误。但如果静态分析能让你在获取值之前进行检查呢?没问题。

<?php

declare(strict_types=1);

use Kafkiansky\Option\Option;

/**
 * @param Option<non-empty-string> $option
 */
function withName(Option $option): void
{
    echo $option->unwrap();
}

使用这段代码,你将因为 unwrap 只能在类型 Some<T> 上调用而从 psalm 获得一个 IfThisIsMismatch 错误。

让我们来修复这个问题

<?php

declare(strict_types=1);

use Kafkiansky\Option\Option;

/**
 * @param Option<non-empty-string> $option
 */
function withName(Option $option): void
{
    if ($option->isSome()) {
        echo $option->unwrap();
    }
}

现在一切正常。

这段代码也存在 NoValue 问题的错误倾向

<?php

declare(strict_types=1);

use Kafkiansky\Option\Option;

/**
 * @param Option<non-empty-string> $option
 */
function withName(Option $option): void
{
    if ($option->isNone()) {
        echo $option->unwrap();
    }
}

但是这段代码没有错误,因为你已经为 None 类型提供了一个默认值,所以你可以调用 unwrap 而不必调用 isSome

<?php

declare(strict_types=1);

use Kafkiansky\Option\Option;

/**
 * @param Option<non-empty-string> $option
 */
function withName(Option $option): void
{
    echo $option
        ->map(
            fn (string $name): string => 'User: '. $name,
            fn (): string => 'anonymous',
        )
        ->unwrap()
    ;
}

而且这段代码也没有错误

<?php

declare(strict_types=1);

use Kafkiansky\Option\Option;

/**
 * @param Option<non-empty-string> $option
 */
function withName(Option $option): void
{
    echo $option->unwrapOr('anonymous');
}

限制

目前这个包与 Psalm 工作得最好,因为 PHPStan 还不知道如何理解 if-this-is 注解。

测试

$ composer phpunit

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件