4 个稳定版本
1.3.0 | 2023年8月20日 |
---|---|
1.2.0 | 2023年5月9日 |
1.1.0 | 2023年4月25日 |
1.0.0 | 2023年4月18日 |
#345 在 Rust 模式
28,005 每月下载量
在 74 个 crate 中使用 (通过 divan)
22KB
161 行
condtype
通过布尔常量在编译时选择 Rust 类型,由 Nikolai Vazquez 提供。
如果你觉得这个库很有用,可以考虑 star 它,以及 赞助 或 一次性捐赠 💖
条件类型
CondType
类型和 condval!
宏通过布尔常量在编译时选择类型,就像 C++ 中的 std::conditional_t
一样。与 Either
类型不同,CondType
/condval!
选择的是直接使用,而不是用 enum
类型包裹。这可以被认为是一种 依赖类型 的形式,但它的能力有限,并且仅限于编译时常量,而不是运行时值。
CondType
在下面的例子中,CondType
根据布尔 泛型常量 的值,别名 &str
或 i32
use condtype::CondType;
let str: CondType<true, &str, i32> = "hello";
let int: CondType<false, &str, i32> = 42;
// Unsized types are also supported:
let str: &CondType<true, str, [u8]> = "world";
condval!
condval!
允许在不指定类型的情况下选择不同类型的值。在以下示例中,val
被推断为是 &str
或 i32
,具体取决于 COND
。
use condtype::condval;
const COND: bool = true;
let val = condval!(if COND {
"hello"
} else {
42
});
assert_eq!(val, "hello");
if let
模式匹配也受到支持
use condtype::condval;
const STR: Option<&str> = Some("hello");
let val = condval!(if let Some(str) = STR {
str.to_uppercase()
} else {
42
});
assert_eq!(val, "HELLO");
特定平台类型
该库可以通过使用特定平台常数的更小尺寸类型来提高某些平台上代码的效率。
在以下示例中,RlimOption
类型可以是 Option<rlim_t>
或 rlim_t
本身,其中如果 rlim_t::MAX
不等于 RLIM_INFINITY
,它可以被当作 Option::None
的哨兵值。
use condtype::{condval, CondType};
use libc::{rlim_t, RLIM_INFINITY};
const RLIM_INFINITY_IS_MAX: bool = RLIM_INFINITY == rlim_t::MAX;
type RlimOption = CondType<RLIM_INFINITY_IS_MAX, Option<rlim_t>, rlim_t>;
const RLIM_NONE: RlimOption = condval!(if RLIM_INFINITY_IS_MAX {
None::<rlim_t>
} else {
rlim_t::MAX
});
// Convert from either `RlimOption` type to `Option` via the `Into` trait:
let rlim_none: Option<rlim_t> = RLIM_NONE.into();
如果没有这个库,可以通过使用 cfg_if!
来达到相同的目标。然而,使用 #[cfg]
需要维护一个平台列表,并且在 RLIM_INFINITY
依赖于 CPU 架构时需要更加细致。
use cfg_if::cfg_if;
use libc::rlim_t;
cfg_if! {
// Platforms where `RLIM_INFINITY != rlim_t::MAX`:
if #[cfg(any(
target_os = "macos",
target_os = "freebsd",
target_os = "solaris",
// ad nauseam...
))] {
type RlimOption = rlim_t;
const RLIM_NONE: RlimOption = rlim_t::MAX;
} else {
type RlimOption = Option<rlim_t>;
const RLIM_NONE: RlimOption = None;
}
}
限制
目前无法使用 CondType
或 condval!
与一个 泛型常量,因为 Rust 还没有将基于布尔值的特实现视为详尽的。一旦该问题得到解决,此库的所有版本都应与泛型常量“正常工作”。
fn generic<const B: bool>() {
let val: CondType<B, &str, i32> = condval!(if B {
"hello"
} else {
42
});
}
安装
此库在 crates.io 上可用,您可以通过在项目目录中运行以下 cargo
命令来使用它
cargo add condtype
或者通过手动将以下内容添加到您项目的 Cargo.toml
[dependencies]
condtype = "1.3.0"
许可证
像 Rust 项目一样,此库可以在 MIT 许可证 或 Apache 许可证(版本 2.0) 下使用。