bosunski / results
Rust-like Result/Option PHP 工具库
Requires
- php: >=8.0
Requires (Dev)
- laravel/pint: ^1.13
- pestphp/pest: ^2.26
- phpstan/phpstan: ^1.10
- phpstan/phpstan-webmozart-assert: ^1.2
README
Results 是一个简单的 (无依赖) PHP 库,它提供了一组辅助函数和类,用于处理可选值和操作的结果。它受到了 Rust 中的 Option
和 Result
类型的影响。实现本身基于名为 ts-results
的 TypeScript 实现。
安装
您可以通过 Composer 安装此库
composer require bosunski/results
使用
演示
您可以在这个 沙盒 中尝试此包
Option
Option
类型表示一个可选值:每个 Option
要么是包含值的 Some
,要么是不包含值的 None
。
<?php use function Bosunski\Results\Option; $some = Option('value'); // Some $none = Option(null); // None
Result
Result
类型是一个表示成功(Ok
)或失败(Err
)的类型。
<?php use function Bosunski\Results\Result; $ok = Result('value'); // Ok $err = Result(new Exception('error')); // Err
辅助函数
该库提供了一组用于创建 Option
和 Result
实例的辅助函数
Some(mixed $value): Some
None(): None
Option(mixed $value): Option
Ok(mixed $value): Ok
Err(Throwable $e): Err
Result(mixed $value): Ok|Err
wrap(callable $fn): Result
示例
PHP 中可以使用 Results 库提供的 Option
和 Result
类型来表示可选值和结果。以下是一些示例
<?php use function Bosunski\Results\Option; use function Bosunski\Results\Result; // Options $some = Option('value'); // Some $none = Option(null); // None // Results $ok = Result('value'); // Ok $err = Result(new Exception('error')); // Err
在上面的示例中
Option('value')
创建了一个包含值的Option
(称为Some
)。Option(null)
创建了一个不包含值的Option
(称为None
)。Result('value')
创建了一个表示成功操作的Result
(Ok
)。Result(new Exception('error'))
创建了一个表示失败操作的Result
(Err
)。
让我们深入了解在 PHP 中使用 Option
和 Result
类型的一些更复杂的示例。
考虑一个可能返回或不返回值的函数。我们可以使用 Option
类型来处理这种不确定性。
<?php use Bosunski\Results\Option as OptionInterface; use function Bosunski\Results\Option; function findUserById($id): OptionInterface { // Assume getUserFromDatabase is a function that returns a User object if found, null otherwise $user = getUserFromDatabase($id); return Option($user); } $userOption = findUserById(123); // We can then handle the optional value using the methods provided by the Option type if ($userOption->isSome()) { $user = $userOption->unwrap(); // Do something with the user } else { // Handle the case where no user was found } // You can also do this $user = $userOption->unwrap() // Throws error if null
现在,让我们考虑一个可能成功或失败的函数。我们可以使用 Result
类型来处理这种情况。
<?php use Bosunski\Results\Result\Result as ResultInterface; use function Bosunski\Results\Result; function divide(int $numerator, int $denominator): ResultInterface { if ($denominator == 0) { return Err(new Exception("Cannot divide by zero")); } else { return Ok($numerator / $denominator); } } $result = divide(10, 0); // We can then handle the result using the methods provided by the Result type if ($result->isOk()) { $value = $result->unwrap(); // Do something with the value } else { $error = $result->unwrapErr(); // Handle the error } // You can also do this $user = $result->unwrap() // Throws error if an error is present
在这些示例中,Option
和 Result
类型提供了一种安全且易于表达的方式来处理可选值和操作的结果。
wrap 函数
wrap
函数是库提供的一个实用函数。它设计用于处理可能抛出错误的操作。wrap
函数执行一个 callable
并返回其结果被包裹在一个 Result
对象中。如果可调用函数抛出异常,wrap
函数会捕获它并返回一个包含异常的 Err
对象。
重要
wrap
函数只会捕获 Throwable
实例。如果你的函数引发了一个致命错误,它将不会被 wrap
捕获。
以下是如何使用 wrap
函数的一个示例
<?php use function Bosunski\Results\wrap; function mightThrowException(): int { if (rand(0, 1) === 1) { throw new Exception('An error occurred'); } return 42; } $result = wrap(mightThrowException(...)); if ($result->isOk()) { echo "Success: " . $result->unwrap(); } else { echo "Error: " . $result->unwrapErr()->getMessage(); }
在这个例子中,mightThrowException
是一个可能会抛出异常的函数。我们将这个函数传递给 wrap
,它执行该函数,捕获 任何 错误并将结果封装在 Result
对象中。然后我们检查结果是否是 Ok
或 Err
的实例,并相应地处理。
wrap
函数提供了一种安全且易于表达的方式来处理可能会抛出错误的操作,让你在不需要处理错误时,能够专注于应用程序逻辑。
贡献
设置项目
你可以通过运行以下命令来安装开发依赖项:
composer install
运行测试
composer run test
许可证
本项目采用 MIT 许可证 许可。