2016-04-28 22 views
2

Rustに10個の空ベクトルの配列を作成したいが、[Vec::new(); 10]はを実装していないため、Vecは機能しません。どのようにすればいいのですか?より一般的に言えば、関数を繰り返し呼び出すことによって配列を初期化するにはどうしたらいいですか?関数を使用して配列を初期化するにはどうすればよいですか?

+1

お試しいただいた内容をお見せできますか?関数やベクトルから配列を返すことは問題ありません。あなたはどちらを試してみましたか? (あなたのタイトルは配列、あなたの質問はベクトルと言います)。 –

+0

よろしくお願いします。それはタイプミスです – user3519580

+0

関連:[デフォルト(構造体値)配列の初期化にはなぜコピーの特性が必要ですか?](http://stackoverflow.com/q/27876588/155423)固定長配列を初期化する適切な方法?](http://stackoverflow.com/q/31360993/155423)。重複しない[非コピー型の大きな固定長配列の初期化](http://stackoverflow.com/q/28656387/155423) – Shepmaster

答えて

2

これは本当に興味深い質問です。私は考えることができる

唯一の安全な解決策は、私は可能な2は

まず

マクロ

macro_rules! array { 
    ($v: expr; 1) => ([$v]); 
    ($v: expr; 2) => ([$v, $v]); 
    ($v: expr; 3) => ([$v, $v, $v]); 
    ($v: expr; 4) => ([$v, $v, $v, $v]); 
    ($v: expr; 5) => ([$v, $v, $v, $v, $v]); 
    // until 32 
} 

let a = array![Vec::new(); 3]; 
を使用して簡単な解決策に近づく見るこの

ようなマクロです

少し冗長ですが、さらにstandard libはこの種の構造を使用します。

セカンド

私は前に答えていたこの質問とotherとの間の接続を実現した後、私ははそうでないことをを示していることをnodrop

extern crate nodrop; 

macro_rules! array { 
    ($e: expr; $n:expr) => (
     { 
      use std::mem; 
      use std::ptr; 
      use nodrop::NoDrop; 

      struct ArrayBuilder<T> { 
       len: usize, 
       data: *mut T, 
      } 

      impl<T> Drop for ArrayBuilder<T> { 
       fn drop(&mut self) { 
        unsafe { 
         while self.len > 0 { 
          let offset = (self.len as isize) - 1; 
          self.len -= 1; 
          ptr::drop_in_place(self.data.offset(offset)); 
         } 
        } 
       } 
      } 

      let mut v: NoDrop<[_; $n]> = NoDrop::new(unsafe { 
       mem::uninitialized() 
      }); 
      // helps type inference for v 
      if false { v[0] = $e; } 
      let mut builder = ArrayBuilder { 
       len: 0, 
       data: (&mut *v as *mut _) as *mut _ 
      }; 
      unsafe { 
       for i in 0..$n { 
        ptr::write(builder.data.offset(i as isize), $e); 
        builder.len = i + 1; 
       } 
      } 
      builder.len = 0; 
      v.into_inner() 
     } 
    ) 
} 

let a = array![Vec::new(); 3]; 

とテストを使用して、このソリューションを書きましたリークメモリ

#[test] 
fn test() { 
    static mut COUNT: usize = 0; 

    #[derive(Debug)] 
    struct X(usize); 

    impl Drop for X { 
     fn drop(&mut self) { 
      println!("drop {:?}", self.0); 
     } 
    } 

    impl X { 
     fn new() -> X { 
      unsafe { 
       if COUNT == 3 { 
        panic!(); 
       } 
       let x = X(COUNT); 
       COUNT += 1; 
       x 
      } 
     } 
    } 

    array![X::new(); 6]; 
} 

このテストでは、X(3)を作成するときにパニックが発生するため、X(0),X(1)X(2)を削除する必要があります。

その他

危険なソリューションhereがあります。

+0

理論的には、任意のnに対してこのような構成を生成できるマクロを作成することは可能でしょうか?さびのマクロが単一の式に拡張されるというルールによって、私自身の試みが邪魔になり、大カッコ内に可変数の式を持つことが難しくなりました。 – user3519580

+0

現在のマクロシステムでは不可能です。 – malbarbo

関連する問題