2017-08-26 48 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變量是獨立的哪種類型的T實際上是雖然foo<T>本身有不同的名稱實例化。

泛型函數的不同實例是否有可能具有不同的靜態變量,因此println!在上例中被調用了兩次?

回答

6

No. 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"); 
    }); 
} 
+0

雖然這可能不是一個好問題,但您知道爲什麼生鏽不支持具有泛型參數的靜態變量嗎? – hfukuda

+1

@hfukuda:不是。可能因爲沒有人需要它足夠嚴重。 –

相關問題