< 返回版块

Matheritasiv 发表于 2023-02-28 23:42

Tags:闭包,类型标记

xItem = &[u8]的一个迭代器,那么闭包|x| x.skip(1).take(1)的类型标记该怎么写?

评论区

写评论
苦瓜小仔 2023-03-01 09:24

op_row的类型标记里面不带std::slice::Chunks<'a1, u8>这个具体的迭代器类型,而写成一种T: Iterator<Item = &'a1 [u8]>的形式?

这不可能:闭包被这样使用 let mut src = op_row(src.data.chunks(src.line_length));,输入参数已经不是(调用者所决定的)泛型,而是已经固定成 Chunks;输出可以是泛型,因为那由调用者决定。

除了生命周期可以改进,其他都没问题。你可以简化一下:

use std::slice::Chunks;
fn region_composite_do<'a, T1, T2>(&mut self, (pos_x, pos_y): (usize, usize), src: &'a Self,
    mut op_row: impl FnMut(Chunks<'a, u8>) -> T1,
    mut op_col: impl FnMut(Chunks<'a, u8>) -> T2)
where T1: Iterator<Item = &'a [u8]>, T2: Iterator<Item = &'a [u8]> {
作者 Matheritasiv 2023-03-01 00:21

这是返回值的类型,好像闭包参数的类型不能写成泛型的形式,必须知道迭代器的具体类型。

fn region_composite_do<'a, 'a1, 'a2, T1, T2>(&mut self, (pos_x, pos_y): (usize, usize), src: &'a Self,
    mut op_row: impl FnMut(std::slice::Chunks<'a1, u8>) -> T1,
    mut op_col: impl FnMut(std::slice::Chunks<'a2, u8>) -> T2)
where T1: Iterator<Item = &'a1 [u8]>, T2: Iterator<Item = &'a2 [u8]>, 'a: 'a1, 'a1: 'a2 {
    let mut src = op_row(src.data.chunks(src.line_length));
    for line in self.data.chunks_mut(self.line_length).skip(pos_y) {
        if let Some(src) = src.next() {
            let mut src = op_col(src.chunks(4));
            for p in line.chunks_mut(4).skip(pos_x) {
                if let Some(src) = src.next() {
                    let c = Color::from(p as &[u8]) + Color::from(src);
                    p[0] = c.get_red_u8();
                    p[1] = c.get_green_u8();
                    p[2] = c.get_blue_u8();
                    p[3] = c.get_alpha_u8();
                } else { break; }
            }
        } else { break; }
    }
}

这段代码我试了好半天才试出来这个可以通过编译的类型标记,有没有什么办法让op_row的类型标记里面不带std::slice::Chunks<'a1, u8>这个具体的迭代器类型,而写成一种T: Iterator<Item = &'a1 [u8]>的形式?

👇
苦瓜小仔: 匿名类型(无法命名的类型)可以用 impl Trait, 所以 x.skip(1).take(1) 的类型通常写为 impl Iterator<Item = &[u8]>。但 impl Trait 无法在所有地方使用。

苦瓜小仔 2023-03-01 00:07

匿名类型(无法命名的类型)可以用 impl Trait, 所以 x.skip(1).take(1) 的类型通常写为 impl Iterator<Item = &[u8]>。但 impl Trait 无法在所有地方使用。

1 共 3 条评论, 1 页