我正在学习生锈并遇到问题。我有这个MCVE:
fn main() {
let mut line = String::new();
std::io::stdin()
.read_line(&mut line)
.expect("Failed to read line");
handle_tokens( line.split_ascii_whitespace() );
}
fn handle_tokens( mut it: std::str::SplitAsciiWhitespace ) {
loop {
match it.next() {
None => return,
Some(s) => println!("{}",s),
}
}
}
String::split_ascii_whitespace
返回一个SplitAsciiWhitespace
对象,因此我在的签名中使用了它handle_tokens
,但是它std::str::SplitAsciiWhitespace
是一种非常特殊的类型。通用的字符串列表迭代器更有意义,因此我可以选择,split_whitespace
也可以只选择通用的字符串列表。
如何使用文档或编译器错误来概括签名handle_tokens
?
这是我独自回答问题的失败尝试:
我可以看到SplitAsciiWhitespace
“特质实现”包括:
impl<'a> Iterator for SplitWhitespace<'a>
这是next()
从哪里来的(我不得不检查源代码以进行验证)。因此,我尝试使用带有fn handle_tokens( mut it: Iterator ) {
but的迭代器:
error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified
--> src/main.rs:10:27
|
10 | fn handle_tokens( mut it: Iterator ) {
| ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>`
好的,Iterator
太通用了,无法使用...我需要告诉编译器它包装了什么。那是有道理的,否则我将无法取消引用它。我不得不再次查看源代码,以了解如何SplitWhitespace
实现Iterator并看到它,type Item = &'a str;
因此我尝试使用Item
with进行指定fn handle_tokens( mut it: Iterator<Item = &str>)
,但是:
error[E0277]: the size for values of type `(dyn std::iter::Iterator<Item = &str> + 'static)` cannot be known at compilation time
--> src/main.rs:10:19
|
10 | fn handle_tokens( mut it: Iterator<Item = &str> ) {
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::iter::Iterator<Item = &str> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
好的,所以我还需要指定一个大小。这很奇怪,因为虽然我知道str
在编译时无法知道的大小,但&str
应该是的大小。
在这一点上我很卡住。当Rust似乎提供了如此强大的内置文档支持时,我也很惊讶必须进行源代码检查。这使我认为我用来回答这个问题的方法是错误的。
您实际上是在正确的道路上。next
确实是在定义的Iterator
,这就是您需要使用的一种。您错过的是Iterator
实际上是* trait`,而不是类型。类型可以受特征限制,因此泛型在这里很方便:
fn handle_tokens<'a, I: Iterator<Item = &'a str>>(mut it: I) { .. }
还有一种特殊的impl-trait语法可以代替使用:
fn handle_tokens<'a>(mut it: impl Iterator<Item = &'a str>) { .. }
但是,不能使用显式指定的类型来调用最后一个示例,即 handle_tokens::<SplitAsciiWhitespace>(iter)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句