3 个版本
0.1.2 | 2022年7月21日 |
---|---|
0.1.1 | 2022年7月20日 |
0.1.0 | 2022年7月20日 |
#1925 在 Rust 模式
18KB
201 行
cismute
在泛型上下文中提供安全的简单转换,模拟稳定 Rust 中的专用。这些函数设计为被编译器优化掉,因此在大多数情况下可能是零成本的。
fn specialized_function<T: 'static>(x: T) -> String {
// We have an efficient algorithm for `i32` and worse algorithm for any other type.
// With `cismute` we can do:
match cismute::owned::<T, i32>(x) {
Ok(x) => format!("got an i32: {x}"),
Err(x) => format!("got something else"),
}
}
assert_eq!(specialized_function(42_i32), "got an i32: 42");
assert_eq!(specialized_function(":)"), "got something else");
cismute::owned
仅适用于 'static
类型。如果您的类型是引用,您应使用 cismute::reference
或 cismute::mutable
。
fn specialized_function<T: 'static>(x: &T) -> String {
// We have an efficient algorithm for `i32` and worse algorithm for any other type.
// With `cismute` we can do:
match cismute::reference::<T, i32>(x) {
Ok(x) => format!("got an i32: {x}"),
Err(x) => format!("got something else"),
}
}
assert_eq!(specialized_function(&42_i32), "got an i32: 42");
assert_eq!(specialized_function(&":)"), "got something else");
还有一个更通用的函数 cismute::value
可以完成这三项。编写所有类型参数可能很麻烦,因此您也可以通过 cismute::value_with
将类型对作为参数传递。
use cismute::Pair;
fn specialized_function<T: 'static>(x: &T) -> String {
match cismute::value_with(Pair::<(T, i32)>, x) {
Ok(x) => format!("got an i32: {x}"),
Err(x) => format!("got something else"),
}
}
assert_eq!(specialized_function(&42_i32), "got an i32: 42");
assert_eq!(specialized_function(&":)"), "got something else");
还有 switch!()
宏和 switch()
函数来匹配一个值与多个类型。
与其他 crate 的比较
-
refl 和 identity 需要提供类型相等的证明来转换。在某些情况下这是不可能的(例如,实现外部的泛型方法时),并且如果需要为不同类型提供可选的证明,则在多个类型上进行零成本切换变得非常困难,如果不是不可能的话。
-
safe-transmute 提供了各种安全的转换,但不提供转换为同一类型。