簡體   English   中英

為什么引用的迭代器項不轉換為特征對象引用?

[英]Why are iterator items which are references not cast to a trait object reference?

我試圖定義一個應該接收迭代器的函數,其中每個項目都是對特征對象的引用。 例如:

use std::fmt::Display;

fn show_items<'a>(items: impl Iterator<Item = &'a Display>) {
    items.for_each(|item| println!("{}", item));
}

當我嘗試在迭代器上調用它時,其中每個項目都是對實現Display的類型的引用:

let items: Vec<u32> = (1..10).into_iter().collect();
show_items(items.iter());

我收到一個錯誤:

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, u32> as std::iter::Iterator>::Item == &dyn std::fmt::Display`
 --> src/lib.rs:9:5
  |
9 |     show_items(items.iter());
  |     ^^^^^^^^^^ expected u32, found trait std::fmt::Display
  |
  = note: expected type `&u32`
             found type `&dyn std::fmt::Display`
note: required by `show_items`
 --> src/lib.rs:3:1
  |
3 | fn show_items<'a>(items: impl Iterator<Item = &'a Display>) {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

為什么&u32不被視為&dyn std::fmt::Display

顯式強制轉換可以正常工作:

show_items(items.iter().map(|item| item as &Display));

它也可以用於單個項目:

fn show_item(item: &Display) {
    println!("{:?}", item);
}
let item: u32 = 1;
show_item(&item);

從類型的隱式轉換Tdyn TraitTrait通過實施T是所謂的未分級的強制 ,一種特殊形式的脅迫。 盡管Rust不太願意使用隱式類型轉換,但強制確實會在強制站點上隱式發生,而在其他地方卻不會。

函數調用參數是強制站點。 這解釋了為什么show_item()函數可以show_item()工作。

還可以使用as運算符顯式執行所有強制。 因此,使用map()的版本可以正常工作。

您對show_items()定義,

fn show_items<'a>(items: impl Iterator<Item = &'a Display>)

另一方面是完全不同的故事。 這里使用的impl語法是的簡寫

fn show_items<'a, I>(items: I)
where
    I: Iterator<Item = &'a dyn Display>,

該函數在迭代器類型上是通用的,並且編譯器驗證您實際傳入的類型是否實現了特征綁定Iterator<Item = &'a dyn Display> 示例代碼中的類型std::slice::Iter<'_, u32>根本沒有,因此出現錯誤。 沒有強制將參數轉換為其他類型以使其實現通用函數所需的某些特征綁定的強制轉換。 還完全不清楚將std::slice::Iter<'_, u32>轉換為通過&dyn Display進行迭代的類型。

請注意,您的函數定義版本由於需要對特征對象進行迭代而不必要地受到限制。 僅要求迭代器項改為實現Display會更自然,更高效:

fn show_items<I>(items: I)
where
    I: IntoIterator,
    I::Item: Display,

(我也將Iterator更改為IntoIterator ,因為這更通用,更方便。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM