在地图闭包中生成新序列时出现奇怪的类型错误

bri*_*tar 2 iterator tuples rust

我正在使用这个问题的答案的策略,我有兴趣生成另一个序列,它是由迭代器映射创建的两个函数:

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,
         summed_signal): (Vec<f64>, Vec<f64>, Vec<f64>) =
        time_1s.map(|time_sample| {
            let sample_440 = (freq * &time_sample).sin();
            let sample_100 = (100.0 * &time_sample).sin();
            let summed_sample = &sample_440 + &sample_100;

            (sample_440, sample_100, summed_sample)
        }).unzip();
}
Run Code Online (Sandbox Code Playgroud)

与闭合指示一样,第三个信号是前两个信号的总和.令人困惑的是我得到的错误:

error[E0271]: type mismatch resolving `<[closure@src/main.rs:17:21: 23:10 freq:_] as std::ops::FnOnce<(f64,)>>::Output == (_, _)`
  --> src/main.rs:23:12
   |
23 |         }).unzip();
   |            ^^^^^ expected a tuple with 3 elements, found one with 2 elements
   |
   = note: expected type `(f64, f64, f64)`
   = note:    found type `(_, _)`
   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::iter::Map<itertools_num::Linspace<f64>, [closure@src/main.rs:11:14: 11:40 delta:_]>, [closure@src/main.rs:17:21: 23:10 freq:_]>`

error[E0308]: mismatched types
  --> src/main.rs:17:9
   |
17 |         time_1s.map(|time_sample| {
   |         ^ expected a tuple with 3 elements, found one with 2 elements
   |
   = note: expected type `(std::vec::Vec<f64>, std::vec::Vec<f64>, std::vec::Vec<f64>)`
   = note:    found type `(_, _)`
Run Code Online (Sandbox Code Playgroud)

我可以理解一个类型错误,但为什么第三个元组项应该被完全忽略?

aSp*_*pex 5

您可以unzip3根据标准unzip创建自定义实现:

trait IteratorUnzip3 {
    fn unzip3<A, B, C, FromA, FromB, FromC>(self) -> (FromA, FromB, FromC) where
        FromA: Default + Extend<A>,
        FromB: Default + Extend<B>,
        FromC: Default + Extend<C>,
        Self: Sized + Iterator<Item=(A, B, C)>,
    {
        let mut ts: FromA = Default::default();
        let mut us: FromB = Default::default();
        let mut vs: FromC = Default::default();

        for (t, u, v) in self {
            ts.extend(Some(t));
            us.extend(Some(u));
            vs.extend(Some(v));
        }

        (ts, us, vs)
    }
}

impl<A, B, C, T: Iterator<Item=(A, B, C)>> IteratorUnzip3 for T{}

fn main() { 
    let freq: f64 = 440.0; 

    let (sine_440, sine_100, summed_signal): (Vec<f64>, Vec<f64>, Vec<f64>) = 
        [1.0, 2.0, 3.0].iter().cloned()
            .map(|time_sample| { 
                let sample_440 = (freq * &time_sample).sin(); 
                let sample_100 = (100.0 * &time_sample).sin(); 
                let summed_sample = &sample_440 + &sample_100; 
                (sample_440, sample_100, summed_sample) 
            }).unzip3(); 

    println!("{:?}\n{:?}\n{:?}", sine_440, sine_100, summed_signal);
}
Run Code Online (Sandbox Code Playgroud)

操场