泛型函数的不同实例是否可能具有不同的静态变量?

时间:2017-08-26 07:23:35

标签: rust

当我在泛型函数中使用静态变量时,泛型函数的每个实例中变量的实体都是相同的。

例如,在此代码中

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>();
}

println!只被调用一次。

我使用Rust操场检查了汇编代码,发现INIT变量与T实际上的类型无关,尽管foo<T>本身用不同的名称实例化。

泛型函数的不同实例是否可以使用不同的静态变量,以便在上面的示例中调用println!两次?

1 个答案:

答案 0 :(得分:7)

没有。 Rust不支持将静态数据绑定到通用参数。

我能想到的最接近的解决方法是使用typemap crate之类的东西来存储每种类型的一个条目。

/*!
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");
    });
}