微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将迭代器值传递给闭包预期类型参数`I`,找到结构`std::slice::Iter`有什么问题?

如何解决将迭代器值传递给闭包预期类型参数`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,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 会有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。