![](/img/trans.png)
[英]Returning a lambda function with parameter types constrained by generic type parameters
[英]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.