问题描述
我想了解以下错误:
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,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,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,)));
}
None => Ok(()),},}
}))
},(f_out,tab_pos_last),)
}
非宏展开的代码不会导致编译错误。它应该与宏扩展代码具有相同的含义(尽管运行时特性略有不同),并且看起来像:
fn detab_go<'a,mut bytes_iter: BytesIter<R>,mut buf_iter: I,{
match buf_iter.next() {
Some(byte) => {
if !is_tab_or_newline(*byte) {
write_u8(f_out,*byte)?;
}
detab_go(
f_out,/*&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,/*&tab_pos_new*/ /*todo!()*/ 1,)
}
None => Ok(()),/* Finished */
}
}
}
}
解决方法
我认为区别在于递归的类型:直接递归调用 detab_go
允许编译器看到 detab_go
接受任意 Iterator<Item=u8>
,而 trampoline
版本似乎修复了 I
- 不允许输入不同的类型。
也许让 detab_go
接受 std::slice::Iter<'_,u8>
而不是一般的 Iterator
会有所帮助。