【问题标题】:it is possible to turn a seft-owned variable to static lifetime?可以将 seft 拥有的变量转换为静态生命周期吗?
【发布时间】:2021-06-12 02:12:13
【问题描述】:

这发生在我身上很多次,例如,

pub struct EmailTemplateMessageBuilder(Translator);

impl EmailTemplateMessageBuilder {
    pub fn new(locale: LanguageIdentifier)  -> Self{
        Self(Translator::new(locale))
    }

    fn render<C>(&self, template_name: &str, email_template: &EmailTemplate, context: &C) -> String {
        let mut template_engine = TinyTemplate::new();
        let translator = self.0;

       //The add_formatter method below has signature: 
       // pub fn add_formatter<F>(&mut self, name: &'template str, formatter: F)
       // where
       // F: 'static + Fn(&Value, &mut String) -> Result<()>

        template_engine.add_formatter(
            "trans", 
           |value: &Value, output: &mut String|  { 
                match value {
                    Value::String(s) => {
                        output.push_str(translator.trans_simple(s).as_ref()); 
        
                        Ok(())
                    }
                    _ => panic!("Unable to translate {}", value),
                }
        });

          template_engine.render("default", context)
            .expect(&format!("Enable to render email template {}", template_name))
    }
}

由于 EmailTemplateMessageBuilder 结构拥有翻译器,我知道它的生命周期比 template_engine 变量长,闭包也是如此, 翻译变量在被调用时应该始终有效。看来我需要一种方法将自有引用变为“静态生命周期”。

注意:

  • Translator 无法实现 Copy trait,因为它依赖于其他未复制的变量。
  • 这段代码在同一个线程中运行,没有未来,没有多个线程。

【问题讨论】:

  • 您是否正在寻找Clone?它的工作方式类似于 Copy,但必须显式调用,并且可用于更多类型。
  • @SilvioMayolo,是的,这是唯一的方法吗?
  • 如果您拥有self,您可以从中移出一个值。但只要该值由self, 拥有,它就会在self 被释放时被释放。故事结束。

标签: rust


【解决方案1】:

看来我需要一种方法将自有引用转为“静态生命周期”。

这就是Rc 的用途。将结构体定义为EmailTemplateMessageBuilder(Rc&lt;Translator&gt;),将translator定义为self.0.clone()clone() 只克隆指针并增加引用计数,因此很便宜。最后,关闭move,使其拥有所有捕获的数据。

【讨论】:

  • 我明白了,非常感谢,终于明白Rc了。
猜你喜欢
  • 2011-09-12
  • 1970-01-01
  • 2013-07-27
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 2019-09-03
相关资源
最近更新 更多