#static #generic #generics #namespaces

nightly generic-statics

Rust的泛型静态

1 个不稳定版本

0.1.0 2024年4月13日

#2997 in Rust模式

MIT/Apache

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

没有运行时依赖