1 个不稳定版本
0.1.0 | 2024年4月13日 |
---|
#2997 in Rust模式
15KB
244 行
generic-statics
此crate为实验性,可能不完全稳定。请自行承担风险。
Rust中缺失泛型静态的解决方案。
use std::{ptr, sync::atomic::{AtomicPtr, Ordering}};
// This code doesn't work.
static A<T>: AtomicPtr<T> = AtomicPtr::new(ptr::null_mut());
let a = A::<usize>.load(Ordering::Relaxed);
使用 generic-statics
use std::sync::atomic::{AtomicPtr, Ordering};
use generic_statics::{define_namespace, Namespace};
define_namespace!(Test);
// This works.
let a = Test::static_generic::<AtomicPtr<usize>>().load(Ordering::Relaxed);
注意事项
此crate仅适用于nightly版本,依赖于 #![feature(asm_const)]
(截至2024-04-10,该功能的稳定化因 feature(inline_const)
而受阻)。
此crate提供的泛型静态使用静态分配(即在运行时没有动态分配)并且几乎是零成本的(除了用于计算静态地址的一些内联汇编指令)。
然而,此crate仅提供最佳努力稳定的地址
use generic_statics::{define_namespace, Namespace};
define_namespace!(Test);
// This is *not* guaranteed but in most cases this will work just fine.
assert_eq!(
Test::static_generic::<usize>() as *const _,
Test::static_generic::<usize>() as *const _
);
所使用的方法依赖于内联汇编为函数的每个单形变体实例化/预留静态数据。不幸的是,内联会返回不同的数据版本,因此不会返回稳定的地址。但是,static_generic
被标记为 #[inline(never)]
,这应该在大多数情况下提供稳定的地址(注意,#[inline(never)]
只是编译器的一个提示,并不能保证任何事情)。
由于内联汇编的限制,目前只允许使用“可清零”的类型。
此crate目前只支持以下目标
- macOS
x86_64
,aarch64
- Linux
x86_64
,aarch64
- FreeBSD
x86_64
,aarch64
- Windows
x86_64