gpt4 book ai didi

types - 从函数返回泛型而在rust中没有泛型参数

转载 作者:行者123 更新时间:2023-12-03 11:42:59 25 4
gpt4 key购买 nike

我目前正在尝试在Rust中编写一个小函数,该函数将通过简单的LISP风格的计算器语言的 token 返回迭代器。我没想到会遇到编译错误。
我第一次编写该函数的尝试是:

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()
}
但是我曾希望能够在这两个选项之间进行选择,即使后者似乎可行,甚至可能不会产生泛型函数。
在前一种情况下,为什么不能使用 where子句指定泛型?
我已经使用 where子句来约束以前出现在返回类型中的通用参数。仅当通用参数也出现在函数的参数中时,这才起作用吗?
任何更多解释这种区别的细节的引用文献都将特别有帮助。

最佳答案

在Rust中,当您在Item<...>列表中指定了生存期或类型参数时,将在使用站点上选择这些生存期或类型参数。
该函数签名表明函数的调用者可以选择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>>;
调用者无法选择那是什么类型。编译器从函数体中推断出实际的类型。

关于types - 从函数返回泛型而在rust中没有泛型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62747289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com