5 个版本 (3 个稳定版本)
2.0.0 | 2020 年 11 月 11 日 |
---|---|
1.1.0 | 2020 年 11 月 11 日 |
1.0.0 | 2019 年 9 月 18 日 |
0.1.1 | 2019 年 9 月 8 日 |
0.1.0 | 2019 年 9 月 8 日 |
在 Rust 模式 中排名第 1578
每月下载量 35
27KB
204 行
These
These
表示数据的 3 分支。可以将其视为 Result
,只是我们有一个额外的情形可以同时包含结果 T
和错误 E
。这在我们可以继续计算最终结果但同时也遇到错误时很有用。
enum These<T, U> {
This(T),
That(U),
Both(T, U)
}
我们有三个构造函数 This
保留 T
,That
保留 U
,和 Both
保留两者。
这里和那里
如果我们想讨论所有 T
,我们使用术语 Here
。这意味着我们可能有一个 This
或 Both
。或者在代码中
use these::These;
fn is_here<T: Copy, U: Copy>(these: &These<T, U>) -> bool {
these.is_this() || these.is_these()
}
如果我们想讨论所有 U
,我们使用术语 There
。这意味着我们可能有一个 That
或 Both
。或者在代码中
use these::These;
fn is_here<T: Copy, U: Copy>(these: These<T, U>) -> bool {
these.is_that() || these.is_these()
}
构造示例
假设我们有一个只允许小于 10 的数字的函数。我们公开一个新类型 LessThanTen
,并期望我们的用户使用 is_less_than_ten
来验证 i8
到这个类型。我们可以使用 Result
并对此进行建模
#[derive(Debug, PartialEq)]
struct LessThanTen(i8);
#[derive(Debug, PartialEq)]
pub enum Error {
IsGreaterThanOrEqualToTen,
}
pub fn is_less_than_ten(i: i8) -> Result<LessThanTen, Error> {
if i < 10 {
Ok(LessThanTen(i))
} else {
Err(Error::IsGreaterThanOrEqualToTen)
}
}
assert_eq!(is_less_than_ten(8), Ok(LessThanTen(8)));
assert_eq!(is_less_than_ten(10), Err(Error::IsGreaterThanOrEqualToTen));
但过了一段时间,我们意识到我们可以开始支持所有小于20的数字。我们可以采取类似的方法,但希望保持向后兼容,并且跟踪遇到大于10的数字的情况。也许我们想要对这些错误进行统计,或者将成功的结果转换为LessThanTen
以保持向后兼容。我们可以使用These
来解决此问题,并可以按照以下方式建模
use these::These;
#[derive(Debug, PartialEq)]
struct LessThanTen(i8);
#[derive(Debug, PartialEq)]
struct LessThanTwenty(i8);
#[derive(Debug, PartialEq)]
pub enum Error {
IsGreaterThanOrEqualToTen,
IsGreaterThanOrEqualToTwenty,
}
pub fn is_less_than_ten(i: i8) -> Result<LessThanTen, Error> {
if i < 10 {
Ok(LessThanTen(i))
} else {
Err(Error::IsGreaterThanOrEqualToTen)
}
}
pub fn is_less_than_twenty(i: i8) -> These<Error, LessThanTwenty> {
if i < 10 {
These::That(LessThanTwenty(i))
} else if i < 20 {
These::Both(Error::IsGreaterThanOrEqualToTen, LessThanTwenty(i))
} else {
These::This(Error::IsGreaterThanOrEqualToTwenty)
}
}
// Convert to the backwards compatible scenario
pub fn backwards_compatible(r: These<Error, LessThanTwenty>) -> Result<LessThanTen, Error> {
r.collapse_these(
|e| Err(e),
|LessThanTwenty(i)| Ok(LessThanTen(i)),
|e, _| Err(e),
)
}
assert_eq!(is_less_than_ten(8), Ok(LessThanTen(8)));
assert_eq!(is_less_than_ten(10), Err(Error::IsGreaterThanOrEqualToTen));
assert_eq!(is_less_than_twenty(8), These::That(LessThanTwenty(8)));
assert_eq!(is_less_than_twenty(10), These::Both(Error::IsGreaterThanOrEqualToTen, LessThanTwenty(10)));
assert_eq!(is_less_than_twenty(20), These::This(Error::IsGreaterThanOrEqualToTwenty));
assert_eq!(backwards_compatible(is_less_than_twenty(8)), Ok(LessThanTen(8)));