Castaway
安全、零成本的向下类型转换,用于有限的编译时特化。
[文档]
请查看[文档]以了解如何使用Castaway及其限制。为了帮助你入门,这里有一个非常简单、完整的Castaway使用示例:
use std::fmt::Display;
use castaway::cast;
/// 类似于`std::string::ToString`,但当`Self`已经是`String`时进行优化。
///
/// 由于标准库允许使用不稳定特性,`ToString`已经使用`specialization`
/// 特性实现了这种优化,但普通的crate无法做到这一点。
pub trait FastToString {
fn fast_to_string(&self) -> String;
}
impl<T: Display> FastToString for T {
fn fast_to_string(&self) -> String {
// 如果`T`已经是字符串,则采用不同的代码路径。
// 单态化后,这个检查将被完全优化掉。
if let Ok(string) = cast!(self, &String) {
// 不调用std::fmt机制,直接克隆字符串。
string.to_owned()
} else {
// 对于任何其他`T`,使用`Display`。
format!("{}", self)
}
}
}
fn main() {
println!("specialized: {}", String::from("hello").fast_to_string());
println!("default: {}", "hello".fast_to_string());
}
最低支持的Rust版本
Castaway支持的最低Rust版本(或称MSRV)为稳定版Rust 1.38或更高,这意味着我们只保证Castaway可以在rustc 1.38及以上版本编译。该版本在CI中进行显式测试,只有在新的次要版本中才可能提高。对支持的最低版本的任何更改都将在发布说明中说明。
这是什么?
这是一个实验性库,在稳定版Rust上实现了零成本的类型向下转换。它始于我读到这个pull请求后的一个思考实验,我想知道是否可能在不使用trait对象的情况下根据具体类型改变泛型函数的行为。我在尝试不同实现并检查示例程序生成的汇编时,偶然发现了我的发现的"零成本"特性。
API与标准库中的Any
有些相似,但Castaway更专注于人体工程学的编译时向下转换,而不是运行时向下转换。与Any
不同,Castaway确实支持在有限场景下安全地转换非'static
引用。如果你需要存储一个或多个实现某个trait的Box<?>
对象,并希望能够向下转换,那么使用Any
会更好。
许可证
本项目的源代码和文档采用MIT许可证。详情请参见LICENSE文件。