Is it possible for different instances of a generi

2019-06-15 20:33发布

When I use a static variable in generic functions, the entities of the variable in each instance of the generic function are all the same.

For instance, in this code

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! is called just once.

I had checked the assembly code using the Rust playground and saw that the INIT variable is independent of which type T actually is although foo<T> themselves are instantiated with different name.

Is it possible for different instance of the generic function to have different static variables so that println! is called twice in the above example?

标签: rust
1条回答
劫难
2楼-- · 2019-06-15 20:54

No. Rust doesn't support having static data tied to a generic parameter.

The closest workaround I can think of would be to use something like the typemap crate to store one entry per type.

/*!
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");
    });
}
查看更多
登录 后发表回答