簡體   English   中英

從 function 返回一個泛型類型,在 rust 中沒有泛型參數

[英]Returning a generic type from a function without generic parameters in rust

我目前正在嘗試在 Rust 中編寫一個小的 function ,它在簡單的 LISP 樣式計算器語言的標記上返回一個迭代器。 當我沒想到時遇到了編譯錯誤。

我第一次嘗試編寫 function 是:

fn tokenizer_for<'a, I>(s: &'a str) -> Peekable<I> where I: Iterator<Item=&'a str> {
    s.split_whitespace()
        .flat_map(
            |word| {
                word.replace("(", "( ").replace(")", " )").split_whitespace()
            }
        )
        .peekable()
}

然而 rustc 回復:

error[E0308]: mismatched types
  --> src/lib.rs:4:5
   |
3  |   fn tokenizer_for<'a, I>(s: &'a str) -> Peekable<I> where I: Iterator<Item=&'a str> {
   |                        -                 ----------- expected `std::iter::Peekable<I>` because of return type
   |                        |
   |                        this type parameter
4  | /     s.split_whitespace()
5  | |         .flat_map(
6  | |             |word| {
7  | |                 word.replace("(", "( ").replace(")", " )").split_whitespace()
8  | |             }
9  | |         )
10 | |         .peekable()
   | |___________________^ expected type parameter `I`, found struct `std::iter::FlatMap`
   |
   = note: expected struct `std::iter::Peekable<I>`
              found struct `std::iter::Peekable<std::iter::FlatMap<std::str::SplitWhitespace<'_>, std::str::SplitWhitespace<'_>, [closure@src/lib.rs:6:13: 8:14]>>`
   = help: type parameters must be constrained to match other types
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

我發現在返回類型中使用impl是有效的(我更喜歡):

fn tokenizer_for(s: &str) -> Peekable<impl Iterator<Item=&str>> {
    s.split_whitespace()
        .flat_map(
            |word| {
                word.replace("(", "( ").replace(")", " )").split_whitespace()
            }
        )
        .peekable()
}

但我曾期望能夠在任一選項之間進行選擇,即使看起來后一種有效的嘗試甚至可能不會產生通用的 function。

為什么我不能在前一種情況下使用where子句來指定泛型類型?

我之前使用where子句來約束出現在返回類型中的泛型參數。 僅當泛型參數也出現在函數的參數中時才有效嗎?

任何能更多解釋這種區別細節的參考資料都會特別有幫助。

在 Rust 中,當您在Item<...>列表中指定了生命周期或類型參數時,將在使用現場選擇這些生命周期或類型參數。

這個 function 簽名說 function 的調用者可以選擇I是什么類型:

fn tokenizer_for<'a, I>(s: &'a str) -> Peekable<I> where I: Iterator<Item=&'a str>;

但這不會編譯,因為返回類型實際上是調用Iter::peekable()的返回類型(即錯誤消息中的類型std::iter::Peekable<std::iter::FlatMap<std::str::SplitWhitespace<'_>, std::str::SplitWhitespace<'_>, [closure@src/lib.rs:6:13: 8:14]>> )。

另一方面,這個簽名表示返回類型只是實現Iterator<Item=&str>>東西

fn tokenizer_for(s: &str) -> Peekable<impl Iterator<Item=&str>>;

調用者不能選擇那是什么類型; 編譯器從 function 主體推斷出實際類型。

暫無
暫無

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

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