#transmute #specialization #safe

无 std cismute

在泛型上下文中安全地将类型转换为自身

3 个版本

0.1.2 2022年7月21日
0.1.1 2022年7月20日
0.1.0 2022年7月20日

#1925Rust 模式

BSD-2-Clause-Patent

18KB
201

cismute

docs badge license: BSD-2-Clause-Patent

在泛型上下文中提供安全的简单转换,模拟稳定 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::referencecismute::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 的比较

  • reflidentity 需要提供类型相等的证明来转换。在某些情况下这是不可能的(例如,实现外部的泛型方法时),并且如果需要为不同类型提供可选的证明,则在多个类型上进行零成本切换变得非常困难,如果不是不可能的话。

  • safe-transmute 提供了各种安全的转换,但不提供转换为同一类型。

无运行时依赖

特性