首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >块()在返回迭代器时仍然借用

块()在返回迭代器时仍然借用
EN

Stack Overflow用户
提问于 2022-10-09 04:43:54
回答 1查看 52关注 0票数 1

使用迭代器进行base85解码。初步实现,所以算法可能是不正确的-只是试图通过借用检查目前。

代码语言:javascript
复制
pub fn decode(indata: impl IntoIterator<Item=impl Borrow<u8>> + 'static) -> impl Iterator<Item=Result<u8>> {
    #[inline]
    fn char85_to_byte(c: u8) -> Result<u8> {
        match c {
            b'0'..=b'9' => Ok(c - b'0'),
            b'A'..=b'Z' => Ok(c - b'A' + 10),
            b'a'..=b'z' => Ok(c - b'a' + 36),
            b'!' => Ok(62),
            b'#' => Ok(63),
            b'$' => Ok(64),
            b'%' => Ok(65),
            b'&' => Ok(66),
            b'(' => Ok(67),
            b')' => Ok(68),
            b'*' => Ok(69),
            b'+' => Ok(70),
            b'-' => Ok(71),
            b';' => Ok(72),
            b'<' => Ok(73),
            b'=' => Ok(74),
            b'>' => Ok(75),
            b'?' => Ok(76),
            b'@' => Ok(77),
            b'^' => Ok(78),
            b'_' => Ok(79),
            b'`' => Ok(80),
            b'{' => Ok(81),
            b'|' => Ok(82),
            b'}' => Ok(83),
            b'~' => Ok(84),
            v => Err(Error::UnexpectedCharacter(v)),
        }
    }

    indata
        .into_iter()
        .map(|v|*v.borrow())
        .filter(|v| !(*v == 32 || *v == 10 || *v == 11 || *v == 13))
        .chunks(5)
        .into_iter()
        .map(|mut v| {
            let (a,b,c,d,e) = (v.next(), v.next(), v.next(), v.next(), v.next());
            let accumulator = u32::from(char85_to_byte(a.unwrap())?)
                + u32::from(b.map_or(Err(Error::UnexpectedEnd), char85_to_byte)?) * 85u32.pow(1)
                + u32::from(c.map_or(Ok(0), char85_to_byte)?) * 85u32.pow(2)
                + u32::from(d.map_or(Ok(0), char85_to_byte)?) * 85u32.pow(3)
                + u32::from(e.map_or(Ok(0), char85_to_byte)?) * 85u32.pow(4);
            Ok([
                Some((accumulator >> 24) as u8),
                c.map(|_|(accumulator >> 16) as u8),
                d.map(|_|(accumulator >> 8) as u8),
                e.map(|_|accumulator as u8)
            ])
        })
        .flatten_ok()
        .filter_map_ok(|v| v)
}

但是,这会产生以下错误:

代码语言:javascript
复制
error[E0716]: temporary value dropped while borrowed
   --> src/lib.rs:96:5
    |
96  |        indata
    |   _____^
    |  |_____|
    | ||
97  | ||         .into_iter()
98  | ||         .map(|v|*v.borrow())
99  | ||         .filter(|v| !(*v == 32 || *v == 10 || *v == 11 || *v == 13))
100 | ||         .chunks(5)
    | ||__________________^ creates a temporary which is freed while still in use
...   |
114 | |              ])
115 | |          })
    | |___________- argument requires that borrow lasts for `'static`
...
118 |    }
    |    - temporary value is freed at the end of this statement

For more information about this error, try `rustc --explain E0716`.

还有什么借来的?我能想到的每一件事都应该以价值来传递。

非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-09 05:30:53

我猜缺少的方法来自于事实上的标准迭代库,即itertools。因此,最小化的例子是:

代码语言:javascript
复制
use itertools::Itertools;

pub fn decode(indata: Vec<u8>) -> impl Iterator<Item = u8> {
    indata.into_iter().chunks(2).into_iter().flatten()
}

游乐场

错误:

代码语言:javascript
复制
error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:4:5
  |
4 |     indata.into_iter().chunks(2).into_iter().flatten()
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
  |     |
  |     creates a temporary which is freed while still in use
  |     argument requires that borrow lasts for `'static`
5 | }
  | - temporary value is freed at the end of this statement

造成此错误的原因是IntoChunks 不能按值迭代。 --仅通过引用;第二个.into_iter()不是在IntoChunks上调用的,而是在对它的引用上调用的。

不知道为什么要以这种方式实施--如果认为可行的话,这可能需要向itertools的作者提出一个问题,甚至需要公关来添加自己的备选方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74002179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档