2017-08-26 12 views
9

汎用関数で静的変数を使用する場合、汎用関数の各インスタンス内の変数のエンティティはすべて同じです。このコードでは例えば汎用関数の異なるインスタンスが異なる静的変数を持つことは可能ですか?

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!は一度だけ呼ばれます。

私は錆の遊び場を使用してアセンブリコードをチェックしINIT変数が実際にfoo<T>ものの自体は別の名前でインスタンス化されているタイプTとは無関係であることを見ていました。

上記の例でprintln!が2回呼び出されるように、ジェネリック関数の異なるインスタンスが異なる静的変数を持つことは可能ですか?

答えて

6

番号錆は、静的データが汎用パラメータに関連付けられていることをサポートしていません。

私が考えることができる最も近い回避策は、typemapクレートのようなものをタイプごとに1つのエントリを格納することです。

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

これは良い質問ではありませんが、一般的なパラメータを持つ静的変数をサポートしていない理由を知っていますか? – hfukuda

+1

@hfukuda:そうですね。おそらく誰もそれを必要としないので、おそらく十分です。 –

関連する問題