使用迭代器进行base85解码。初步实现,所以算法可能是不正确的-只是试图通过借用检查目前。
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)
}但是,这会产生以下错误:
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`.还有什么借来的?我能想到的每一件事都应该以价值来传递。
非常感谢。
发布于 2022-10-09 05:30:53
我猜缺少的方法来自于事实上的标准迭代库,即itertools。因此,最小化的例子是:
use itertools::Itertools;
pub fn decode(indata: Vec<u8>) -> impl Iterator<Item = u8> {
indata.into_iter().chunks(2).into_iter().flatten()
}错误:
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的作者提出一个问题,甚至需要公关来添加自己的备选方案。
https://stackoverflow.com/questions/74002179
复制相似问题