当结构的一个实例需要对另一个实例的引用时的生命周期问题
Problems with lifetimes when one instance of a struct needs a reference to another
我正在尝试用 SFML 和 Rust 编写一个简单的游戏,但借用检查器被证明是我在这个旅程中最大的敌人。
在很多情况下,SFML 需要引用另一个对象。在下面的代码中,我需要对字体的引用,否则文本不会向用户显示任何内容。
问题是,我已经尝试了很多东西,但引用本身永远不够长。如果我在 draw 方法上创建 Text 对象显然有效,但我想避免在应用程序的主循环内创建东西。
这种情况是不是应该检查一下不安全的操作?有没有满足我需求的Rc、RefCell、Box等的组合?
如果可能的话,请尝试向我解释我应该做什么以及我目前的心态有什么问题。
extern crate sfml;
use sfml::system::{ Clock, Vector2f };
use sfml::graphics::{ Color, Font, RenderTarget, RenderWindow, Text, Transformable };
pub struct FpsMeter<'a> {
position: Vector2f,
clock: Clock,
value: f32,
text: Text<'a>
}
impl<'a> FpsMeter<'a> {
pub fn new() -> Self {
let font = match Font::new_from_file("assets/sansation.ttf") {
Some(fnt) => fnt,
None => panic!("Cannot open resource: sansation.ttf"),
};
let mut text = Text::new_init(
&format!("FPS: {}", 0),
&font,
20
).expect("Could not create text");
FpsMeter {
position: Vector2f::new(0., 0.),
clock: Clock::new(),
value: 0.,
text: text,
}
}
pub fn set_position2f(&mut self, x: f32, y: f32) {
self.position.x = x;
self.position.y = y;
}
pub fn restart(&mut self) {
self.value = 1. / self.clock.restart().as_seconds();
}
pub fn draw(&mut self, window: &mut RenderWindow) {
self.text.set_position(&self.position);
self.text.set_color(&Color::white());
window.draw(&self.text);
}
}
我不熟悉 rust-sfml,所以我可能误读了你的问题,但它应该看起来像这样。
您有一个 Font
和 Text
(您无法控制,它们是由库为您构建的),其中 Text
包含对 Font
的引用。简体:
struct Font;
struct Text<'a> { font: &'a Font }
然后你有一个 FpsMeter
(你控制)有一个 Text
字段。再次简化:
struct FpsMeter<'a> {
text: Text<'a>
}
现在,如果是这样的话,我认为您不能使用创建 FpsMeter
的相同方法来创建 Text
(或至少 Font
),因为对 Font
的引用无法逃脱构造函数的堆栈帧。您需要将 pre-built Text
传递给您的构造函数。例如:
impl<'a> FpsMeter<'a> {
fn new(txt: Text<'a>) -> FpsMeter<'a> {
FpsMeter { text: txt }
}
}
或者可能:
impl<'a> FpsMeter<'a> {
fn new(fnt: &'a Font) -> FpsMeter<'a> {
FpsMeter { text: Text { font: fnt } }
}
}
我正在尝试用 SFML 和 Rust 编写一个简单的游戏,但借用检查器被证明是我在这个旅程中最大的敌人。
在很多情况下,SFML 需要引用另一个对象。在下面的代码中,我需要对字体的引用,否则文本不会向用户显示任何内容。
问题是,我已经尝试了很多东西,但引用本身永远不够长。如果我在 draw 方法上创建 Text 对象显然有效,但我想避免在应用程序的主循环内创建东西。
这种情况是不是应该检查一下不安全的操作?有没有满足我需求的Rc、RefCell、Box等的组合?
如果可能的话,请尝试向我解释我应该做什么以及我目前的心态有什么问题。
extern crate sfml;
use sfml::system::{ Clock, Vector2f };
use sfml::graphics::{ Color, Font, RenderTarget, RenderWindow, Text, Transformable };
pub struct FpsMeter<'a> {
position: Vector2f,
clock: Clock,
value: f32,
text: Text<'a>
}
impl<'a> FpsMeter<'a> {
pub fn new() -> Self {
let font = match Font::new_from_file("assets/sansation.ttf") {
Some(fnt) => fnt,
None => panic!("Cannot open resource: sansation.ttf"),
};
let mut text = Text::new_init(
&format!("FPS: {}", 0),
&font,
20
).expect("Could not create text");
FpsMeter {
position: Vector2f::new(0., 0.),
clock: Clock::new(),
value: 0.,
text: text,
}
}
pub fn set_position2f(&mut self, x: f32, y: f32) {
self.position.x = x;
self.position.y = y;
}
pub fn restart(&mut self) {
self.value = 1. / self.clock.restart().as_seconds();
}
pub fn draw(&mut self, window: &mut RenderWindow) {
self.text.set_position(&self.position);
self.text.set_color(&Color::white());
window.draw(&self.text);
}
}
我不熟悉 rust-sfml,所以我可能误读了你的问题,但它应该看起来像这样。
您有一个 Font
和 Text
(您无法控制,它们是由库为您构建的),其中 Text
包含对 Font
的引用。简体:
struct Font;
struct Text<'a> { font: &'a Font }
然后你有一个 FpsMeter
(你控制)有一个 Text
字段。再次简化:
struct FpsMeter<'a> {
text: Text<'a>
}
现在,如果是这样的话,我认为您不能使用创建 FpsMeter
的相同方法来创建 Text
(或至少 Font
),因为对 Font
的引用无法逃脱构造函数的堆栈帧。您需要将 pre-built Text
传递给您的构造函数。例如:
impl<'a> FpsMeter<'a> {
fn new(txt: Text<'a>) -> FpsMeter<'a> {
FpsMeter { text: txt }
}
}
或者可能:
impl<'a> FpsMeter<'a> {
fn new(fnt: &'a Font) -> FpsMeter<'a> {
FpsMeter { text: Text { font: fnt } }
}
}