簡體   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