< 返回版块

rdigua 发表于 2020-06-23 18:25

Tags:rust

buffer是从二进制文件读取的Vec;

   let mut buffer: std::vec::Vec<u8>=Vec::new();
   file.read_to_end(&mut buffer);

下面一段从Vec(u8) 转成Vec(u32) 请问 怎么用closure 来完成? let u32_buffer:Vec=buffer.iter().enumerate().....collect();

    let mut u32_buffer:Vec<u32>=Vec::new();
    let mut byte_u8:[u8;4]=[0;4];
    for (i, n) in buffer.iter().enumerate() {
        let k = (i %4) as usize;
        if (i % 4)==0 && i !=0 {
            u32_buffer.push(u32::from_le_bytes(byte_u8));
          //  print!("{:#?},{}",byte_u8,n);
        };
        byte_u8[k]=*n;
    }
    u32_buffer.push(u32::from_le_bytes(byte_u8));

评论区

写评论
作者 rdigua 2020-06-23 21:56

谢谢 ok!

正好下面报错 不能这样 expected struct std::vec::Vec, found closure

let cl=|buffer:&mut Vec<u8>|{//你要的closure
        let mut u32_buffer:Vec<u32>=Vec::new();
        let mut byte_u8:[u8;4]=[0;4];
        for (i, n) in buffer.iter().enumerate() {
            let k = (i %4) as usize;
            if (i % 4)==0 && i !=0 {
                u32_buffer.push(u32::from_le_bytes(byte_u8));
            //  print!("{:#?},{}",byte_u8,n);
            };
            byte_u8[k]=*n;
        }
        u32_buffer.push(u32::from_le_bytes(byte_u8));
        u32_buffer//这里是closure要的返回值,故不加分号
    };

--
👇
Neutron3529: 如果你能保证buffer的长度是4的倍数,或许你根本不需要closure

(use std::convert::TryInto;)
buffer.iter_mut().into_slice().chunks(4).map(|x|u32::from_le_bytes(x.try_into().unwrap())).collect::<Vec<u32>>()

这段话跟你的程序,在保证buffer长度是4的倍数的情况下,输出一致,但简单很多

--
👇
rdigua: ....

Neutron3529 2020-06-23 20:49

如果你能保证buffer的长度是4的倍数,或许你根本不需要closure

(use std::convert::TryInto;)
buffer.iter_mut().into_slice().chunks(4).map(|x|u32::from_le_bytes(x.try_into().unwrap())).collect::<Vec<u32>>()

这段话跟你的程序,在保证buffer长度是4的倍数的情况下,输出一致,但简单很多

--
👇
rdigua: ....

作者 rdigua 2020-06-23 19:27

Great. Thanks. 脑子慢 反应不过来。

--
👇
Neutron3529: 看明白你想做什么了

如果用closure,直接写不行吗?

fn main(){
    let mut a=vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4];
    dbg!(a.iter_mut().into_slice().chunks(4).map(|x|u32::from_le_bytes([*x.get(0).unwrap(),*x.get(1).unwrap_or(&0),*x.get(2).unwrap_or(&0),*x.get(3).unwrap_or(&0)])).collect::<Vec<u32>>());//总觉得这个已经够脏了,没想到closure还能写得更难看些
    dbg!(305419896-0x12345678);
    dbg!(16909060-0x01020304);
    let cl=|buffer:&mut Vec<u8>|{//你要的closure
        let mut u32_buffer:Vec<u32>=Vec::new();
        let mut byte_u8:[u8;4]=[0;4];
        for (i, n) in buffer.iter().enumerate() {
            let k = (i %4) as usize;
            if (i % 4)==0 && i !=0 {
                u32_buffer.push(u32::from_le_bytes(byte_u8));
            //  print!("{:#?},{}",byte_u8,n);
            };
            byte_u8[k]=*n;
        }
        u32_buffer.push(u32::from_le_bytes(byte_u8));
        u32_buffer//这里是closure要的返回值,故不加分号
    };
    dbg!(cl(&mut vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4]));
}

--
👇
rdigua: 已经check掉了 如果不是4的倍数 说明格式不对 直接退出

--
👇
Neutron3529: 看着这个需求就想一个unsafe把Vec的指针转换成Vec的指针……

有一个问题,如果Vec的长度不是4的倍数,尾巴应该怎么处理?

我的意思是,vec![53,42]跟vec![53,42,0,0]应该转换成相同的u32吗?

--

如果上面那句话正确的话,你可以试试 .iter_mut().into_slice().chunks(4).map(|x|(不确定collect怎么写,或许可以用u32::from之类的东西)).collect()

一个比较脏的实现是这样的:

fn main(){
    let mut a=vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4];
    dbg!(a.iter_mut().into_slice().chunks(4).map(|x|u32::from_be_bytes([*x.get(0).unwrap(),*x.get(1).unwrap_or(&0),*x.get(2).unwrap_or(&0),*x.get(3).unwrap_or(&0)])).collect::<Vec<u32>>());
    dbg!(305419896-0x12345678);
    dbg!(16909060-0x01020304);
}
Neutron3529 2020-06-23 19:18

看明白你想做什么了

如果用closure,直接写不行吗?

fn main(){
    let mut a=vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4];
    dbg!(a.iter_mut().into_slice().chunks(4).map(|x|u32::from_le_bytes([*x.get(0).unwrap(),*x.get(1).unwrap_or(&0),*x.get(2).unwrap_or(&0),*x.get(3).unwrap_or(&0)])).collect::<Vec<u32>>());//总觉得这个已经够脏了,没想到closure还能写得更难看些
    dbg!(305419896-0x12345678);
    dbg!(16909060-0x01020304);
    let cl=|buffer:&mut Vec<u8>|{//你要的closure
        let mut u32_buffer:Vec<u32>=Vec::new();
        let mut byte_u8:[u8;4]=[0;4];
        for (i, n) in buffer.iter().enumerate() {
            let k = (i %4) as usize;
            if (i % 4)==0 && i !=0 {
                u32_buffer.push(u32::from_le_bytes(byte_u8));
            //  print!("{:#?},{}",byte_u8,n);
            };
            byte_u8[k]=*n;
        }
        u32_buffer.push(u32::from_le_bytes(byte_u8));
        u32_buffer//这里是closure要的返回值,故不加分号
    };
    dbg!(cl(&mut vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4]));
}

--
👇
rdigua: 已经check掉了 如果不是4的倍数 说明格式不对 直接退出

--
👇
Neutron3529: 看着这个需求就想一个unsafe把Vec的指针转换成Vec的指针……

有一个问题,如果Vec的长度不是4的倍数,尾巴应该怎么处理?

我的意思是,vec![53,42]跟vec![53,42,0,0]应该转换成相同的u32吗?

--

如果上面那句话正确的话,你可以试试 .iter_mut().into_slice().chunks(4).map(|x|(不确定collect怎么写,或许可以用u32::from之类的东西)).collect()

一个比较脏的实现是这样的:

fn main(){
    let mut a=vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4];
    dbg!(a.iter_mut().into_slice().chunks(4).map(|x|u32::from_be_bytes([*x.get(0).unwrap(),*x.get(1).unwrap_or(&0),*x.get(2).unwrap_or(&0),*x.get(3).unwrap_or(&0)])).collect::<Vec<u32>>());
    dbg!(305419896-0x12345678);
    dbg!(16909060-0x01020304);
}
作者 rdigua 2020-06-23 19:08

已经check掉了 如果不是4的倍数 说明格式不对 直接退出

--
👇
Neutron3529: 看着这个需求就想一个unsafe把Vec的指针转换成Vec的指针……

有一个问题,如果Vec的长度不是4的倍数,尾巴应该怎么处理?

我的意思是,vec![53,42]跟vec![53,42,0,0]应该转换成相同的u32吗?

--

如果上面那句话正确的话,你可以试试 .iter_mut().into_slice().chunks(4).map(|x|(不确定collect怎么写,或许可以用u32::from之类的东西)).collect()

一个比较脏的实现是这样的:

fn main(){
    let mut a=vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4];
    dbg!(a.iter_mut().into_slice().chunks(4).map(|x|u32::from_be_bytes([*x.get(0).unwrap(),*x.get(1).unwrap_or(&0),*x.get(2).unwrap_or(&0),*x.get(3).unwrap_or(&0)])).collect::<Vec<u32>>());
    dbg!(305419896-0x12345678);
    dbg!(16909060-0x01020304);
}
Neutron3529 2020-06-23 19:07

看着这个需求就想一个unsafe把Vec的指针转换成Vec的指针……

有一个问题,如果Vec的长度不是4的倍数,尾巴应该怎么处理?

我的意思是,vec![53,42]跟vec![53,42,0,0]应该转换成相同的u32吗?

--

如果上面那句话正确的话,你可以试试 .iter_mut().into_slice().chunks(4).map(|x|(不确定collect怎么写,或许可以用u32::from之类的东西)).collect()

一个比较脏的实现是这样的:

fn main(){
    let mut a=vec![0x12_u8, 0x34, 0x56, 0x78,1,2,3,4];
    dbg!(a.iter_mut().into_slice().chunks(4).map(|x|u32::from_be_bytes([*x.get(0).unwrap(),*x.get(1).unwrap_or(&0),*x.get(2).unwrap_or(&0),*x.get(3).unwrap_or(&0)])).collect::<Vec<u32>>());
    dbg!(305419896-0x12345678);
    dbg!(16909060-0x01020304);
}
1 共 6 条评论, 1 页