当我在泛型函数中使用静态变量时,泛型函数的每个实例中的变量的实体都是相同的.
例如,在此代码中
fn foo<T>() {
use std::sync::{Once, ONCE_INIT};
static INIT: Once = ONCE_INIT;
INIT.call_once(|| {
// run initialization here
println!("Called");
});
}
fn main() {
foo::<i64>();
foo::<i64>();
foo::<isize>();
}
Run Code Online (Sandbox Code Playgroud)
println! 只召唤一次.
我已经使用Rust playground检查了汇编代码,并看到INIT变量T实际上与哪种类型无关,尽管foo<T>它们本身用不同的名称实例化.
是否有可能通用函数的不同实例具有不同的静态变量,因此println!在上面的示例中调用两次?
不,Rust不支持将静态数据绑定到通用参数.
我能想到的最接近的解决方法是使用像typemap箱子这样的东西来存储每种类型的一个条目.
/*!
Add to `Cargo.toml`:
```cargo
[dependencies]
lazy_static = "0.2.8"
typemap = "0.3.3"
```
*/
#[macro_use] extern crate lazy_static;
extern crate typemap;
fn main() {
foo::<i64>();
foo::<i64>();
foo::<isize>();
}
fn foo<T: 'static>() {
use std::marker::PhantomData;
use std::sync::Mutex;
use typemap::{ShareMap, TypeMap};
// Use `fn(T)` as it avoids having to require that `T` implement
// `Send + Sync`.
struct Key<T>(PhantomData<fn(T)>);
impl<T: 'static> typemap::Key for Key<T> {
type Value = ();
}
lazy_static! {
static ref INIT: Mutex<ShareMap> = Mutex::new(TypeMap::custom());
}
INIT.lock().unwrap().entry::<Key<T>>().or_insert_with(|| {
println!("Called");
});
}
Run Code Online (Sandbox Code Playgroud)