首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从字符串的迭代器中分离和flat_map

如何从字符串的迭代器中分离和flat_map
EN

Stack Overflow用户
提问于 2018-12-08 08:47:30
回答 2查看 2.4K关注 0票数 4

是否有一种不使用iter而不使用into_iter的方法使其工作正常?

代码语言:javascript
复制
let strings: Vec<String> = vec!["1 2".to_string(), "3 4".to_string()];
strings.into_iter().flat_map(|str| str.split(" "));

问题是

代码语言:javascript
复制
error[E0515]: cannot return value referencing function parameter `str`
 --> src/lib.rs:3:40
  |
3 |     strings.into_iter().flat_map(|str| str.split(" "));
  |                                        ---^^^^^^^^^^^
  |                                        |
  |                                        returns a value referencing data owned by the current function
  |                                        `str` is borrowed here

当使用iter而不是into_iter时,我会得到一个引用迭代器,所有的东西都能工作,但是我想知道是否有可能在String的迭代器上完成这个工作。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-08 08:59:30

代码的问题在于您正在执行以下操作:

  1. 你正在用into_iter消耗你的矢量
  2. 因此,在闭包中,您使用的是String值,您用split借入该值
  3. 在临时迭代器中,保存对此字符串的引用。

结论:您正在尝试返回一个局部变量的引用。

要解决此问题,必须从拆分字符串中创建拥有的字符串,并收集它们以不再保存引用:

代码语言:javascript
复制
fn main() {
    let strings = vec!["1 2".to_string(), "3 4".into()];
    let result = strings.into_iter().flat_map(|str| str.split(" ").map(str::to_owned).collect::<Vec<_>>());

    println!("{:?}", result.collect::<Vec<_>>());
}

实际上,如果一开始不消耗该载体,成本就会更低:

代码语言:javascript
复制
fn main() {
    let strings = vec!["1 2".to_string(), "3 4".into()];
    let result = strings.iter().flat_map(|str| str.split(" ")).map(str::to_owned);

    println!("{:?}", result.collect::<Vec<_>>());
}
票数 5
EN

Stack Overflow用户

发布于 2020-08-14 02:31:50

我也遇到了同样的问题,最后创建了一个迭代器,它拥有字符串的所有权,下面是代码。既然你是按空间分裂的,它应该适合

代码语言:javascript
复制
struct Words {
    buf: String,
    offset: usize,
}

impl Words {
    fn new(buf: String) -> Words {
        Words { buf, offset: 0 }
    }
}

impl Iterator for Words {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        let s = &(self.buf)[self.offset..];
        let left = s.chars().take_while(|x| x.is_whitespace()).count();
        let right = left + s[left..].chars().take_while(|x| !x.is_whitespace()).count();
        if left < right {
            self.offset += right;
            return Some(String::from(&s[left..right]));
        }

        None
    }
}

在这里我是如何使用它的

代码语言:javascript
复制
fn read_file<'a>(buf: impl BufRead) -> impl Iterator<Item = String> {
    buf.lines().filter_map(Result::ok).flat_map(Words::new)
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53680955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档