【问题标题】:How to store a field that only take reference to String created in `::new()`?如何存储只引用`::new()`中创建的字符串的字段?
【发布时间】:2023-03-26 15:35:01
【问题描述】:

在下面的代码中,我应该如何在A 中存储B 字段?假设我不能更改definition of B

作为 Rust 的新手,我搜索了 Google,其中大多数都解释了错误发生的原因。我可以理解编译错误,但我不知道如何修复它。或者在这种情况下存储字段是不好的设计?还有其他解决方案吗?

谢谢!

use std::io::Read;

struct A<'a> {
    b: B<'a>,
}

impl<'a> A<'a> {
    pub fn new(mut reader: impl Read) -> Self {
        let mut s = String::new();
        reader.read_to_string(&mut s);

        let b = B { b: &s };
        A { b }
    }
}

// From 3rd party library, can't change the struct!
struct B<'a> {
    b: &'a str,
}

fn main() {}

【问题讨论】:

  • 你不能(通常有一些方法,但你不想要它)。从几分钟开始研究这个板条箱,它看起来并没有被大量使用,因为它缺乏做你想做的事情的方法。我建议你创建一个想法,请求一个 to_owned 函数,该函数将使内部的 CoW 拥有。
  • @Stargateur 感谢您的建议。您能否也指出“某种方式”的关键字? :)
  • 我没有这样做是有原因的
  • 答案是“不要那样做”。是什么?这取决于您的用例。

标签: rust reference lifetime


【解决方案1】:

好吧,在这种情况下,您需要一些东西来拥有数据。所以只要让你的A 拥有它,然后有一个方法从A 创建B 类型:

struct A {
    s: String,
}

// From 3rd party library, can't change the struct!
struct B<'a> {
    b: &'a str,
}

impl A {
    pub fn new(mut reader: impl Read) -> Self {
        let mut s = String::new();
        reader.read_to_string(&mut s);

        A { s }
    }

    fn as_b(&self) -> B {
        B { b: &self.s }
    }
}

Playground

【讨论】:

  • 感谢您提供简单的解决方案。我还有一个问题,如果构造B 很耗时,有没有办法加快对as_b 的多次调用?
  • @SaddlePoint,你可以用#[inline] 标记它,这样编译器以后可能会尝试优化它。否则我认为它不会对性能产生太大影响。
猜你喜欢
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
相关资源
最近更新 更多