rust - 将(迭代器)值传递给闭包(预期类型参数`I`,找到结构`std::slice::Iter`)有什么问题?
问题描述
我想了解以下错误:
error[E0308]: mismatched types
--> src/tabs.rs:70:44
|
43 | fn detab_go<'a, I, R, W>(
| - this type parameter
...
70 | f_out, bytes_iter, buf_iter,
| ^^^^^^^^ expected type parameter `I`, found struct `std::slice::Iter`
|
= note: expected type parameter `I`
found struct `std::slice::Iter<'_, u8>`
导致错误的代码如下所示(从我一直在处理的宏扩展而来):
fn detab_go<'a, I, R, W>(
f_out: &mut W,
bytes_iter: BytesIter<R>,
buf_iter: I,
tab_pos_last: usize,
) -> Result<(), Error>
where
I: Iterator<Item = &'a u8>,
R: Read,
W: Write,
{
tailcall::trampoline::run_res(
#[inline(always)]
|(f_out, mut bytes_iter, mut buf_iter, tab_pos_last)| {
Ok(tailcall::trampoline::Finish({
match buf_iter.next() {
Some(byte) => {
if !is_tab_or_newline(*byte) {
write_u8(f_out, *byte)?;
}
return Ok(tailcall::trampoline::Recurse((
f_out, bytes_iter, buf_iter, 1,
)));
}
None => match bytes_iter.next() {
Some(buf_new) => {
let buf_test: Vec<u8> = buf_new?;
let buf_iter = buf_test.iter();
return Ok(tailcall::trampoline::Recurse((
f_out, bytes_iter, buf_iter, 1,
)));
}
None => Ok(()),
},
}
}))
},
(f_out, bytes_iter, buf_iter, tab_pos_last),
)
}
非宏扩展代码不会导致编译错误。它应该与宏扩展代码具有相同的含义(尽管运行时特性略有不同),并且看起来像:
fn detab_go<'a, I, R, W>(
f_out: &mut W,
mut bytes_iter: BytesIter<R>,
mut buf_iter: I,
tab_pos_last: usize,
) -> Result<(), Error>
where
I: Iterator<Item = &'a u8>,
R: Read,
W: Write,
{
match buf_iter.next() {
Some(byte) => {
if !is_tab_or_newline(*byte) {
write_u8(f_out, *byte)?;
}
detab_go(
f_out, bytes_iter, buf_iter,
/*&tab_pos_new*/ /*todo!() */ 1,
)
}
None => {
match bytes_iter.next() {
Some(buf_new) => {
let buf_test: Vec<u8> = buf_new?;
let buf_iter = buf_test.iter(); //shadow
detab_go(
f_out, bytes_iter, buf_iter,
/*&tab_pos_new*/ /*todo!()*/ 1,
)
}
None => Ok(()), /* Finished */
}
}
}
}
解决方案
我认为区别在于递归的类型:直接detab_go
递归调用允许编译器看到detab_go
接受任意的Iterator<Item=u8>
,而trampoline
版本似乎修复了I
- 不允许不同类型作为输入。
也许它有助于detab_go
接受 astd::slice::Iter<'_, u8>
而不是泛型Iterator
。
推荐阅读
- java - 为什么 CriteriaBuilder 不像驼峰式那样工作
- swift - 防止立即调用 sink 的 receiveValue 闭包
- java - While 循环跳过用户输入
- c# - 在复选框选择时,使用列表视图字段更新数据库
- c++ - 分配私有缓冲区并使用指针修改内容
- c# - 关于 C# 中“this”语句的简单问题
- c# - 如何将新成员添加到初始化的表达式树?
- flutter - flutter_native_admob 预加载广告
- javascript - 用户在 HTML 表中选择一行后填充列表框的最佳方法是什么?
- android - RecyclerView 适配器 AndroidStudio 中的问题