我是该语言的新手,仍在与借阅检查器作斗争。我已经看到一些库使用 new() 函数,也就是不带参数的构造函数,并且它可以工作。基本上这意味着,返回的数据是在 new 的函数范围内创建的,并且不会在 new 的范围结束时被删除。
当我自己尝试这个时,借用检查器不会让这个代码通过。除了将 i32 可变引用作为参数传递给构造函数之外,如何进行这项工作。
我错过了什么吗?
#[derive(Debug)]
struct B<'a> {
b: &'a i32
}
#[derive(Debug)]
struct A<'a> {
one: B<'a>
}
impl<'a> A<'a> {
fn new() -> A<'a> {
// let mut b = 10i32;
A {
one: B{b: &mut 10i32}
}
}
}
fn main() {
let a = A::new();
println!("A -> {:?}", a);
}
编译器错误。
main.rs:15:19: 15:24 error: borrowed value does not live long enough
main.rs:15 one: B{b: &mut 10i32}
^~~~~
main.rs:12:20: 17:3 note: reference must be valid for the lifetime 'a as defined on the block at 12:19...
main.rs:12 fn new() -> A<'a> {
main.rs:13 // let mut b = 10i32;
main.rs:14 A {
main.rs:15 one: B{b: &mut 10i32}
main.rs:16 }
main.rs:17 }
main.rs:12:20: 17:3 note: ...but borrowed value is only valid for the block at 12:19
main.rs:12 fn new() -> A<'a> {
main.rs:13 // let mut b = 10i32;
main.rs:14 A {
main.rs:15 one: B{b: &mut 10i32}
main.rs:16 }
main.rs:17 }
error: aborting due to previous error
根据要求,这是我正在尝试使用的实际示例。有这个 GUI 库(Conrod),它有一些实例化它的步骤。就像下面的例子一样。
let assets = find_folder::Search::ParentsThenKids(3, 3)
.for_folder("assets").unwrap();
let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
let theme = Theme::default();
let glyph_cache = GlyphCache::new(&font_path).unwrap();
let ui = &mut Ui::new(glyph_cache, theme);
我的计划是将应用程序的绘图封装到一个结构中。那将有一个构造函数和一些辅助方法。为此,我必须有一个具有该类型实例的字段,该conrod::Ui<GlyphCache<'a>>
类型是上述 ui 变量的类型。
我认为向 main 添加东西(我的意思是在 main 中完成所有分配),可能不是最好的做事方式。
let mut app_ui = app::AppUi::new(); // This would encapsulate all of the above configuration lines.
// use the ui here
for e in evets {
app_ui.handle_input();
app_ui.render();
}
AppUi的实现。它不完整,但应该显示总体思路。只是为了确保我们在同一页面上,该类型conrod::Ui<GlyphCache<'a>>
需要一个生命周期参数。我想拥有与结构相同的生命周期。我知道如何做到这一点的唯一方法是让结构本身获取生命周期参数,并将其传递给 UI 类型。
pub struct AppUi<'a> {
pub ui: conrod::Ui<GlyphCache<'a>>,
pub count: u16
}
impl<'a> AppUi<'a> {
pub fn new() -> AppUi<'a> {
let assets = find_folder::Search::ParentsThenKids(3, 3)
.for_folder("assets").unwrap();
let font_path = assets.join("FiraSans-Regular.ttf");
let theme = Theme::default();
let glyph_cache = GlyphCache::new(&font_path).unwrap();
AppUi {
ui: conrod::Ui::new(glyph_cache, theme),
count: 0
}
}
}
========================
我采用的解决方案,最终奏效了(至少现在有效)。是创建一个辅助函数,它会返回一个 glyph_cache 并使用它。我不确定它是否是惯用的 Rust,现在只会使用它。可能应该习惯于使用借用检查器。
pub struct AppUi<'a> {
pub ui: conrod::Ui<GlyphCache<'a>>,
pub count: u16
}
impl<'a> AppUi<'a> {
pub fn new() -> AppUi<'a> {
AppUi {
ui: conrod::Ui::new(GlyphCache::new(&get_default_font_path()).unwrap(), Theme::default()),
count: 0
}
}
}
pub fn get_default_font_path() -> PathBuf {
find_folder::Search::ParentsThenKids(3, 3)
.for_folder("assets")
.unwrap()
.join("FiraSans-Regular.ttf")
}