是否可以将seft拥有的变量转换为静态生存期



这种情况经常发生在我身上,例如

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,因为它依赖于未复制的其他变量
  • 此代码在同一个线程中运行,没有未来,没有多个线程

我似乎需要一种方法来将自己拥有的引用转换为"静态生存期"。

这就是Rc的作用。将结构体定义为EmailTemplateMessageBuilder(Rc<Translator>),将translator定义为self.0.clone()clone()只克隆指针并增加引用计数,所以它很便宜。最后,将闭包设为move,这样它就拥有所有捕获的数据。

最新更新