【问题标题】:Rust E0597 - borrowed value does not live long enoughRust E0597 - 借来的价值活得不够长
【发布时间】:2019-11-23 04:55:00
【问题描述】:

好吧,我在 Rust 上大约有一个月的时间,并且在其中做更多平凡的任务只是为了锻炼。我遇到了炉甘石板条箱,可以从 excel 中读取数据。我以为我在理解挖洞和所有权方面做得很好,但这是新的,甚至阅读其他一些示例并查看文档也无助于解释它,或者我至少没有遇到它。所以一个基本的for循环

 for row in r.rows() {
        let writer1 = row[11].to_string(); 
        if let Some(cap) = exp.captures(&writer1) { // borrow here
            println!("{} --- {}", &cap[1], &cap[2]);
        } else {
            println!("{}", &writer1); // and borrow here
        }
        // This works fine... great
        // writer1 is type String
        // row     is type &[calamine::datatype::DataType]

        let doing_this: Vec<&str> = writer1.split_whitespace().collect();

        vecs.push(doing_this); // assume vecs exists above for
    }

当我将集合“doing_this”推送到向量中时,会出现 E0597 错误。任何人都可以帮助解释发生了什么吗?我假设有生命周期,但我已经从列中创建了一个字符串并获得了所有权。

【问题讨论】:

  • writer1 位于循环范围内。 vecs 住在外面。 writer1 在循环结束时被丢弃,但vecs 可能稍后会使用。但它的内容doing_this 取决于(参考)writer1 的删除内容。如果doing_thisVec&lt;String&gt;(拥有),就没有问题。
  • 我跟着你@CoronA do_this 持有一个 &str 对 writer1 的引用,最终超出了范围。虽然 split_whitespace 不允许 collect 是底层字符串以外的任何东西,因为它是一个 &str 迭代器,所以如果你使用 collect 它必须是一个 Vec。我对编码并不陌生,但这与思考方式不同。我添加了我的解决方案,尽管我知道必须有一些更规范的东西。我希望有一个 clone().collect()...
  • 你应该可以使用.map(String::from),它会做同样的事情而不会产生额外的关闭噪音。您不能在此处使用克隆,因为您提供的是 &amp;str's。并不是说这是一件坏事,&amp;String 通常是代码异味,因为您提供了不必要的间接性而几乎没有收益。此外,您使用的方法故意提供&amp;str,因为您并不总是想要复制数据,这既提高了性能又不会分配更多的内存,除非您自己使用String::from/str::to_owned 声明。跨度>
  • 您可能会发现阅读What are the differences between Rust's String and str? 会有所帮助
  • @Sahsahae 由于“临时错误”,我发现自己无法使用该值,因此我对中间体使用了 let 绑定并克隆它,这样我就不会收到这些错误。所以因为我做了一个克隆,我不想继续克隆它或用 &writer1[] 因为那是一个 &str iter co collect is &str 直到我克隆它。

标签: rust


【解决方案1】:
        // changed this 
        let doing_this: Vec<&str> = writer1.split_whitespace().collect();


        // to this
        let doing_this: Vec<String> =
            writer1.split_whitespace().map(|x| x.to_owned()).collect();

        // or as suggested to clean up the closure
        let doing_this: Vec<String> =
            writer1.split_whitespace().map(String::from).collect();

【讨论】:

    猜你喜欢
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多