Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for different instances of a generic function to have different static variables?

Tags:

rust

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?

like image 837
hfukuda Avatar asked Aug 26 '17 07:08

hfukuda


People also ask

Is it possible to have multiple instances of a static variable?

If you find that you need multiple instances of a static variable, this is a strong indication that you should not be using static variables in the first place. Yes, if the same class is loaded in different class loaders, then each copy of the class will have its own statics. However, the only code that can refer statically...

Which method can access static variables and instance variables directly?

Instance method can access static variables and static methods directly. Static methods can access the static variables and static methods directly. Static methods can’t access instance methods and instance variables directly.

What is the difference between static and instance methods in Java?

Static methods vs Instance methods in Java. Instance method are methods which require an object of its class to be created before it can be called. To invoke a instance method, we have to create an Object of the class in within which it defined.

Where are static member variables defined in a class?

member variables. If a class's member variable is static, however, only one instance of the variable exists in memory. All objects of that class have access to that one variable. Static member variables are declared inside the class declaration. Where are static member variables defined? Outside the class declaration.


1 Answers

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");
    });
}
like image 129
DK. Avatar answered Oct 16 '22 16:10

DK.