#traits #dyn #vec #generics #any

dync

为容器化类型提供比 dyn Trait 更高效的替代方案

14 个版本

0.5.7 2023年11月11日
0.5.6 2023年11月4日
0.5.3 2022年5月11日
0.5.0 2020年10月13日
0.1.0 2020年5月4日

#180Rust 模式

每月 46 次下载
3 个 crate 中使用 (via meshx)

MIT/Apache

255KB
5K SLoC

dync

为容器化类型提供比 dyn Trait 更高效的替代方案。

On crates.io On docs.rs Build status Coverage (codecov)

概述

此 crate 旨在通过在安全 API 中向用户提供对动态虚函数表的控制来填补 Rust 动态特性系统的空白。此库处于原型阶段,不建议用于生产环境。

目前仅实现了未类型化的 VecSlice。提供了兼容传统、类型化容器的 Value 类型,如 VecDequeHashMap

值得注意的是,dync 引入了以下类型

  • VecCopy<V> - 一个基于虚函数表泛型的 Copy 类型同质集合
  • VecDyn<V> - 一个基于虚函数表泛型的同质集合
  • SliceCopy<V> (和 SliceCopyMut<V>) - 一个基于虚函数表泛型的 Copy 类型的同质切片(和可变切片)
  • Slice<V> (和 SliceMut<V>) - 一个基于虚函数表泛型的类型同质切片(和可变切片)
  • BoxValue<V> - 任意大小的未类型化boxed值
  • SmallValue<V> - 一个适合于 usize 的未类型化值
  • ValueRef<V> (和 ValueMut<V>) - 一个未类型化值引用(和可变引用)
  • CopyValueRef<V> (以及 CopyValueMut<V>) - 一种未类型化的 Copy 类型值引用(和可变引用)。

这些 Copy 变体之间的主要区别是它们不需要指定的析构函数指针,这使得它们更简单,可能也更高效。然而,基准测试并未揭示 Copy 变体有任何性能优势,因此建议默认总是使用完全动态的变体(例如,使用 VecDyn 而不是 VecCopy,使用 Slice 而不是 SliceCopy)。此外,Copy 变体可能在未来被弃用,以简化 API。

示例

创建存储所有元素单个虚拟函数表的同构未类型化 Vec

use dync::VecDrop; // VecDyn<DropVTable>
// Create an untyped `Vec`.
let vec: VecDrop = vec![1_i32,2,3,4].into();
// Access elements either by downcasting to the underlying type.
for value_ref in vec.iter() {
    let int = value_ref.downcast::<i32>().unwrap();
    println!("{}", int);
}
// Or downcast the iterator directly for more efficient traversal.
for int in vec.iter_as::<i32>().unwrap() {
    println!("{}", int);
}

上面的 VecDrop 类型默认为空虚拟表(除析构函数外),当需要以某种方式处理包含的值时并不十分有用。 dync 提供了对常见标准库特质的支持,例如

  • Drop
  • Clone
  • PartialEq
  • std::hash::Hash
  • std::fmt::Debug
  • SendSync
  • 更多功能即将推出

因此,要生成可打印类型的 VecDyn,我们可以这样做

use dync::{VecDyn, traits::DebugVTable};
// Create an untyped `Vec` of `std::fmt::Debug` types.
let vec: VecDyn<DebugVTable> = vec![1_i32,2,3,4].into();
// We can now iterate and print value references (which inherit the VTable from the container)
// without needing a downcast.
for value_ref in vec.iter() {
    println!("{:?}", value_ref);
}

更多示例请参阅 exmaples 目录。

注意事项

此库不包含提供的类型的序列化/反序列化功能,因为这些需要在虚拟表中处理序列化和反序列化函数,这超出了此库的范围。对于序列化和反序列化,建议简单地转换未类型化集合为类型化集合(例如,使用 VecDrop -> Vec<T>)。

许可证

此存储库的许可证是以下两者之一

任选其一。

依赖项

~32–375KB