Rust 返回迭代器(或任何其他特性)的正确方法是什么?

Rust 返回迭代器(或任何其他特性)的正确方法是什么?,rust,Rust,下面的Rust代码编译并运行时没有任何问题 fn main() { let text = "abc"; println!("{}", text.split(' ').take(2).count()); } 在那之后,我尝试了这样的东西。。。。但它没有编译 fn main() { let text = "word1 word2 word3"; println!("{}", to_words(text).take(2).count()); } fn to_word

下面的Rust代码编译并运行时没有任何问题

fn main() {
    let text = "abc";
    println!("{}", text.split(' ').take(2).count());
}
在那之后,我尝试了这样的东西。。。。但它没有编译

fn main() {
    let text = "word1 word2 word3";
    println!("{}", to_words(text).take(2).count());
}

fn to_words(text: &str) -> &Iterator<Item = &str> {
    &(text.split(' '))
}

运行此操作的正确代码是什么。。。。我的知识差距在哪里?

我发现让编译器来指导我很有用:

fn to_words(text: &str) { // Note no return type
    text.split(' ')
}
编辑提供:

错误[E0308]:类型不匹配
-->src/lib.rs:5:5
|
5 |文本分割(“”)
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^`
|
=注意:应为类型“”()`
找到类型“std::str::Split”{
|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
遵循编译器的建议并将其复制粘贴为我的返回类型(稍加清理):

如何使用它有一些限制。您只能返回单个类型(没有条件!),并且必须在自由函数或固有实现上使用

盒装 如果您不介意损失一点效率,可以返回一个

找到类型`std::iter::Filter`
在某些情况下,这些闭包可以替换为函数,这些函数可以命名为:

fn odd_numbers() -> () {
    fn f(&v: &i32) -> bool {
        v % 2 != 0
    }
    (0..100).filter(f as fn(v: &i32) -> bool)
}
找到类型`std::iter::Filter bool>`
并遵照上述建议:

use std::{iter::Filter, ops::Range};

type Odds = Filter<Range<i32>, fn(&i32) -> bool>;

fn odd_numbers() -> Odds {
    fn f(&v: &i32) -> bool {
        v % 2 != 0
    }
    (0..100).filter(f as fn(v: &i32) -> bool)
}
使用std:{iter::Filter,ops::Range};
类型比值=过滤器布尔>;
fn奇数()->赔率{
fn f&v:&i32)->bool{
v%2!=0
}
(0..100).过滤器(f作为fn(v:&i32)->bool)
}
处理条件句
如果需要有条件地选择迭代器,请参阅。

谢谢,这对我帮助很大。“技巧”为了让编译器指导您,这是非常有用的,我将来肯定会使用它……是的,这是非常难看的!我希望RFC能够成为发行候选。虽然包装类型可以很好地隐藏复杂性,但我发现最好只使用
类型
别名,因为使用新类型意味着您的迭代器无法实现t类似于
RandomAccessIterator
的特性,即使基础迭代器支持。是的!类型别名支持泛型参数。例如,许多库使用
Type LibraryResult=Result
作为便利,类似于
IoResult
,这也只是一个类型别名。您能否澄清为什么必须添加
'a
生活在
框中
?这意味着什么?我一直认为这只是一个界限,也就是说“T可能只依赖于某个生命,至少只要
'a
”。@torkleyy可能会回答你的问题,或者会回答你的问题?如果没有,我会鼓励你搜索你的问题,如果你找不到,问一个新的问题。
fn to_words<'a>(text: &'a str) -> Box<dyn Iterator<Item = &'a str> + 'a> {
    Box::new(text.split(' '))
}

fn main() {
    let text = "word1 word2 word3";
    println!("{}", to_words(text).take(2).count());
}
use std::str;

struct Wrapper<'a>(str::Split<'a, char>);

impl<'a> Iterator for Wrapper<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        self.0.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.0.size_hint()
    }
}

fn to_words(text: &str) -> Wrapper<'_> {
    Wrapper(text.split(' '))
}

fn main() {
    let text = "word1 word2 word3";
    println!("{}", to_words(text).take(2).count());
}
use std::str;

type MyIter<'a> = str::Split<'a, char>;

fn to_words(text: &str) -> MyIter<'_> {
    text.split(' ')
}

fn main() {
    let text = "word1 word2 word3";
    println!("{}", to_words(text).take(2).count());
}
fn odd_numbers() -> () {
    (0..100).filter(|&v| v % 2 != 0)
}
fn odd_numbers() -> () {
    fn f(&v: &i32) -> bool {
        v % 2 != 0
    }
    (0..100).filter(f as fn(v: &i32) -> bool)
}
use std::{iter::Filter, ops::Range};

type Odds = Filter<Range<i32>, fn(&i32) -> bool>;

fn odd_numbers() -> Odds {
    fn f(&v: &i32) -> bool {
        v % 2 != 0
    }
    (0..100).filter(f as fn(v: &i32) -> bool)
}