关于Rayon库的一个小问题记录

问题如下:

#[cfg(feature = "parallel")]
use rayon::prelude::*;

pub struct A;
pub trait T1 {}
impl T1 for A {}

pub struct B;
pub trait T2 {
    type S: T1;
}
impl T2 for B {
    type S = A;
}

fn test<T: T2>(a: [T::S; 3], b: &[u64]) {
    b.par_iter();   //正常
    a.par_iter();   //错误
}

编译,出现如下错误:

error[E0599]: the method `par_iter` exists for array `[<T as T2>::S; 3]`, but its trait bounds were not satisfied
  --> src/main.rs:27:7
   |
27 |     a.par_iter();
   |       ^^^^^^^^
   |
   = note: the following trait bounds were not satisfied:
           `&[<T as T2>::S; 3]: IntoParallelIterator`
           which is required by `[<T as T2>::S; 3]: rayon::iter::IntoParallelRefIterator`
           `&[<T as T2>::S]: IntoParallelIterator`
           which is required by `[<T as T2>::S]: rayon::iter::IntoParallelRefIterator`

b能编译通过,a却不能通过,当尝试加上 IntoParallelIterator 也不行时,我本人是比较纳闷的,但出现问题不要慌,心平气和地顺藤摸瓜才能找到解决问题的途径!于是带着问题去看了下源码,发现:

/// This implementation requires const generics, stabilized in Rust 1.51.
impl<'data, T: Sync + 'data, const N: usize> IntoParallelIterator for &'data [T; N] {
    type Item = &'data T;
    type Iter = Iter<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        <&[T]>::into_par_iter(self)
    }
}

/// This implementation requires const generics, stabilized in Rust 1.51.
impl<'data, T: Send + 'data, const N: usize> IntoParallelIterator for &'data mut [T; N] {
    type Item = &'data mut T;
    type Iter = IterMut<'data, T>;

    fn into_par_iter(self) -> Self::Iter {
        <&mut [T]>::into_par_iter(self)
    }
}
  • 对于不可变引用类型的切片,需要满足Sync traint bound
  • 对于不可变引用类型的切片,需要满足Send traint bound

于是修改代码,编译通过

#[cfg(feature = "parallel")]
use rayon::prelude::*;

pub struct A;
pub trait T1 {}
impl T1 for A {}

pub struct B;
pub trait T2 {
    type S: T1 + Sync;
}
impl T2 for B {
    type S = A;
}

fn test<T: T2>(a: [T::S; 3], b: &[u64]) {
    b.par_iter();   //正常
    a.par_iter();   //正常
}

猜你喜欢

转载自blog.csdn.net/qq_34793644/article/details/127006148