繁体   English   中英

为Vec添加实现后,为什么Rust编译器不使用预期的trait实现 <T> ?

[英]Why does the Rust compiler not use the expected trait implementation once I add an implementation for Vec<T>?

我正在尝试实现一个能够从文件中提取不同类型的值的阅读器。 有一个File结构表示文件资源(以及访问其内容的方法),还有一个Reader特性,可以根据结果类型提取值。 (虚拟)实现看起来像这样( playground ):

use std::io::Result;

mod file {
    use std::io::Result;

    pub struct File {/* ... */}

    pub trait Reader<T> {
        fn read(&mut self) -> Result<T>;
    }

    impl Reader<u32> for File {
        fn read(&mut self) -> Result<u32> {
            // Dummy implementation
            Ok(10)
        }
    }

    impl Reader<u8> for File {
        fn read(&mut self) -> Result<u8> {
            // Dummy implementation
            Ok(0)
        }
    }

    impl Reader<bool> for File {
        fn read(&mut self) -> Result<bool> {
            // Dummy implementation
            Ok(false)
        }
    }
}

use file::{File, Reader};

impl<T: Default> Reader<Vec<T>> for File
where
    File: Reader<T> + Reader<u32>,
{
    fn read(&mut self) -> Result<Vec<T>> {
        let count: u32 = self.read()?;
        let mut array: Vec<T> = Vec::with_capacity(count as usize);
        for _ in 0..count {
            let mut item: T = self.read()?;
            array.push(item);
        }

        Ok(array)
    }
}

fn main() {
    let mut file = File {};
    let _v: Vec<u8> = file.read().unwrap();
}

在我添加Reader<Vec<T>>实现之前,一切正常。 向量作为u32存储在文件中,表示元素表示后面的元素数。 编译器给出以下错误:

error[E0308]: try expression alternatives have incompatible types
  --> src/main.rs:41:26
   |
41 |         let count: u32 = self.read()?;
   |                          ^^^^^^^^^^^^
   |                          |
   |                          expected u32, found type parameter
   |                          help: try wrapping with a success variant: `Ok(self.read()?)`
   |
   = note: expected type `u32`
              found type `T`

即使我指定File实现Reader<T>Reader<u32> ,它似乎仍然停留在Reader<T>

更奇怪的是,如果我只保留2个Reader特性的实现(例如删除Reader<bool> ),代码编译没有任何问题( playground )。

为什么编译器不能发现它应该使用Reader<u32>实现进行count初始化? 我应该改变什么?

我找到了一个解决方法,但我仍然有兴趣理解为什么编译器无法自动解决它:

let count: u32 = (self as &mut Reader<u32>).read()?;

据报道,问题是锈蚀/锈病#54344

编译器无法弄清楚它应该使用Reader<u32>实现来let count: u32 = ... 这是一个编译器错误,因为Tself.read()在该行上的使用方式没有关系。 一个.read()调用的返回类型似乎是在不应该确定另一个.read()调用的返回类型时!

另外,如果它不是一个bug,那么除了Reader<u8>Reader<u32> u32 Reader<u32>Reader<T>实现没有什么区别,但正如@rodrigo指出的那样, Reader<bool>的存在Reader<bool>实现会触发此错误。

请注意? (这相当于下面显示的match )与错误无关,因为在直接获取Result<u32>时仍然会收到错误:

let count_result: Result<u32> = self.read(); // error happens here
let count: u32 = match count_result {
    std::result::Result::Ok(val) => val,
    std::result::Result::Err(err) => {
        return std::result::Result::Err(std::convert::From::from(err))
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM