Rust Can';找不到正确的生存期参数来存储加载的字体

Rust Can';找不到正确的生存期参数来存储加载的字体,rust,sdl-2,lifetime-scoping,Rust,Sdl 2,Lifetime Scoping,因此,我正在rust中构建一个游戏引擎,但是我在寻找正确的生命周期参数/语法来存储sdl2库渲染所需的字体数据方面遇到了问题 这是我目前正在做的一个简化版本,但它没有编译。据我所知,由ttf.load\u Font()给出的Font对象的第一个生存期参数必须与ttf对象本身的生存期相匹配,但我无法找到正确的语法或数据结构来告诉编译器该生存期关系 我目前的理解是,ttf作为数据成员与FontManager具有相同(或更短)的生存期,并且创建的任何Font对象都将有一个与创建它的ttf对象关联的生存

因此,我正在rust中构建一个游戏引擎,但是我在寻找正确的生命周期参数/语法来存储sdl2库渲染所需的字体数据方面遇到了问题

这是我目前正在做的一个简化版本,但它没有编译。据我所知,由
ttf.load\u Font()
给出的
Font
对象的第一个生存期参数必须与
ttf
对象本身的生存期相匹配,但我无法找到正确的语法或数据结构来告诉编译器该生存期关系

我目前的理解是,
ttf
作为数据成员与
FontManager
具有相同(或更短)的生存期,并且创建的任何
Font
对象都将有一个与创建它的
ttf
对象关联的生存期。所以,
FontManager恐慌了!(“{:?}”,e),
Ok(font)=>{self.font=Some(font);}
}
}
}
fn main()->结果{
设ttf=sdl2::ttf::init().map_err(|e | e.to_string())?;
让mut fm=FontManager{ttf,font:None};

加载字体(std::path::path::new(“Arial.ttf”,16);//我没有立即找到有意义地使用这个库的方法。也许要做的事情是将
Sdl2TtfContext
放入
Rc
,使用
safe
代码将
和'Sdl2TtfContext
转换成
和'static Sdl2TtfContext
,并将
Fontt
放入一个新的存储库的结构中
Font
Rc
一起。您需要一个自定义的
Drop
实现,它将
Font
放在
Rc
之前。我不太理解这里的
Pin
类型,它们似乎在这个上下文中可能很有用。这个库中的生命周期有点古怪,它们的工作方式更像C而不是Rust,这将使它们很难使用。指定“
”ttf
”生存期是上下文本身的生存期。因此,上下文必须比字体寿命长。在这种情况下,最好的解决方案可能只是将上下文存储在一个静态变量中,这样您就可以得到一个对它的
&
静态引用,因为看起来您一次只能有一个上下文。请参阅,以了解不同的方法o获取全局/静态变量。我认为这里最好的选择是
once\u cell::unsync::Lazy
。在我看来,它微小的、微观的开销非常值得我们的方便(以及安全/安心)。
mod sdl2;

struct FontManager<'a> {
  pub ttf: sdl2::ttf::Sdl2TtfContext,
  pub font: Option<sdl2::ttf::Font<'a, 'static>>,
}

impl<'a> FontManager<'a> {
  pub fn load_font(&'a mut self, path: &std::path::Path, size: usize) {
    match self.ttf.load_font(&self.ttf, path, size as u16) {
      Err(e) => panic!("{:?}", e),
      Ok(font) => { self.font = Some(font); }
    }
  }
}

fn main() -> Result<(), String> {
  let ttf = sdl2::ttf::init().map_err(|e| e.to_string())?;
  let mut fm = FontManager { ttf, font: None };
  fm.load_font(std::path::Path::new("Arial.ttf", 16); // <- error: 'fm' does not live long enough

  // ...main game loop...

} // <- error: 'fm' dropped here while still borrowed