2016-10-10 8 views
3

私はコンパクトな方法で地図をクローニング悩み抱えている(?):クローニング推論されたとのstd :: ITER ::地図入力

extern crate itertools_num; 

use itertools_num::linspace; 

fn main() { 
    // 440Hz as wave frequency (middle A) 
    let freq: f64 = 440.0; 
    // Time vector sampled at 880 times/s (~Nyquist), over 1s 
    let delta: f64 = 1.0/freq/2.0; 
    let time_1s = linspace(0.0, 1.0, (freq/2.0) as usize) 
     .map(|sample| { sample * delta}); 

    let sine_440: Vec<f64> = time_1s.map(|time_sample| { 
     (freq * time_sample).sin() 
    }).collect(); 

    let sine_100: Vec<f64> = time_1s.map(|time_sample| { 
     (100.0 * time_sample).sin() 
    }).collect(); 
} 

私はこのコードを取得するエラーが

`time_1s` moved here because it has type `std::iter::Map<itertools_num::Linspace<f64>, [[email protected]/linear_dft.rs:12:14: 12:40 delta:&f64]>`, which is non-copyable 
です理解しやすいですが、私が代わりに time_1s.clone()を使用しようとすると、私も理解できる

note: the method `clone` exists but the following trait bounds were not satisfied: `[[email protected]/linear_dft.rs:12:14: 12:40 delta:_] : std::clone::Clone` 
error: the type of this value must be known in this context 
    (freq * time_sample).sin() 

を得るが、保存

クロージャ内のlet foo: f64内の(freq * time_sample).sin()は、それを返す前には何の効果もありません。

このような状況で私は何をすべきでしょうか?私がしたかったのは、時間ベクトルを複数回使用することでした。

+0

重要なエラーは、クロージャがクローン可能でないという事実です。 http://stackoverflow.com/q/27883509/155423; http://stackoverflow.com/q/21933892/155423; http://stackoverflow.com/q/39803231/155423; http://stackoverflow.com/q/28011803/155423。 – Shepmaster

答えて

6

一つの方法に:map以来

は、自分で一度だけ、それを超えるだけのループであり、必要以上の反復またはクローンを発生させることなく、これを行うために簡単かつ効率的な方法のように思える、イテレータを消費しますtime_1sを2回一緒に使用し、最後に解凍する:

extern crate itertools_num; 

use itertools_num::linspace; 

fn main() { 
    // 440Hz as wave frequency (middle A) 
    let freq: f64 = 440.0; 
    // Time vector sampled at 880 times/s (~Nyquist), over 1s 
    let delta: f64 = 1.0/freq/2.0; 
    let time_1s = linspace(0.0, 1.0, (freq/2.0) as usize) 
      .map(|sample| { sample * delta}); 

    let (sine_440, sine_100): (Vec<f64>, Vec<f64>) = time_1s.map(|time_sample| { 
     ((freq * time_sample).sin(), 
     (100.0 * time_sample).sin()) 
    }).unzip(); 
} 
+0

これはいいです、私は 'unzip 'を全く考えていませんでした。私はどのような配分がこの設定で起こるのだろうか?私はそれがまったく大きな影響を及ぼさないと思っていますが、私はまだ興味があります。私はRustの反復子/列挙子の内部について十分に精通していません。 –

+0

私が探していた機能的な配合があるので、この回答を受け入れます。 (さらにドットがあります。) –

3

私の元の答えは、イテレータの3つの列挙を引き起こしました。理想的には、2回の繰り返しを探していました。

let time_1s = linspace(0.0, 1.0, (freq/2.0) as usize) 
    .map(|sample| { sample * delta}); 

let mut sine_100 = Vec::new(); 
let mut sine_440 = Vec::new(); 

for time_sample in time_1s { 
    sine_100.push((100.0 * time_sample).sin()); 
    sine_440.push((freq * time_sample).sin()); 
} 

println!("{:?}", sine_100); 
println!("{:?}", sine_440); 
+0

これは間違いなく最も読みやすく多様なソリューションです。 –

関連する問題