【问题标题】:Rust lifetimes : Static reference lives to short to be fed into a function?Rust 生命周期:静态引用生命周期太短而无法输入函数?
【发布时间】:2018-02-20 19:40:47
【问题描述】:

我发现生锈了,一生都很难过。

例如,我正在尝试一些 GUI:

#[macro_use]extern crate native_windows_gui as nwg;

use nwg::{Ui, Event, EventArgs};

nwg_template!(
    head: setup_ui<&'static str>,
    controls: [
        ("MainWindow", nwg_window!(title="Test1"; size=(180,50))),
        ("SetButton", nwg_button!(parent="MainWindow"; visible=false)),
        ("BackButton", nwg_button!(parent="MainWindow"; text="<"; position=(10,10); size=(30,30))),
        ("Text", nwg_textbox!(parent="MainWindow"; readonly=true; position=(40,10); size=(100,30))),
        ("NextButton", nwg_button!(parent="MainWindow"; text=">"; position=(140,10); size=(30,30)))
    ];
    events: [
        ("SetButton", "Set", Event::Click, |app,_,_,_| {
            let display = nwg_get_mut!(app; ("Text", nwg::TextBox));
            let index = nwg_get!(app; ("Index", &str));
            display.set_text(**index);
        }),
        ("BackButton", "Back", Event::Click, |_,_,_,_| {}),
        ("NextButton", "Next", Event::Click, |_,_,_,_| {})
    ];
    resources: [];
    values: [
        ("Index", "Test")
    ]
);

fn create_ui(data: &'static str) -> Result<Ui<&'static str>, nwg::Error> {
   let app: Ui<&'static str>;

    match Ui::new() {
        Ok(ui) => { app = ui; },
        Err(e) => { return Err(e) }
    }

    if let Err(e) = setup_ui(&app) {
        return Err(e);
    }

    app.pack_value(&"Data", &data);
    app.trigger(&"SetButton", Event::Click, EventArgs::None);

    if let Err(e) =app.commit() {
        Err(e)
    } else {
        Ok(app)
    }
}

fn main() {
    let data = "Foo";
    let _ui = create_ui(data).expect("Oups");
    nwg::dispatch_events();
}

我不明白为什么在函数create_ui 中,data 的寿命不够长,无法在app.pack_value() 中被喂食。

在我看来,'static 的生命周期可以让它存活足够长的时间。

但是编译器认为它在create_ui 的末尾死亡,因此不能用作app.pack_value("Data", &amp;data);

我做错了什么?

【问题讨论】:

  • "..它 create_ui..结束时死掉了。"
  • “我做错了什么?”您在没有提供错误消息文本的情况下抱怨错误。如果没有所有信息,我们将无法提供帮助

标签: rust lifetime


【解决方案1】:

不知道确切的错误,很难确定,但我的猜测是:

fn create_ui(data: &'static str) -> Result<Ui<&'static str>, nwg::Error>

参数data会借用一串静态生命周期。也就是说,它指向的东西(字符串数据)具有静态生命周期,但引用本身具有函数的生命周期。现在让我们看看native_windows_gui crate 中的函数:

fn pack_value<T: Into<Box<T>> + 'static>(&self, id: &ID, value: T)

参数value 必须具有静态生命周期。还有一些其他要求,但它们不相关。现在回到你的代码:

app.pack_value(&"Data", &data);

您正在传递pack_value data 的引用,这已经是一个引用。也就是说,您传递的参数的类型为&amp;&amp;'static str。外部引用(您传递的那个)没有静态生命周期:它的生命周期与您的函数一样长。

C++ 中的等价物类似于

result_type create_ui(static char *str) {
    Ui app = ...;
    app.pack_value(&"Data", &str);
}

这在 C++ 中编译得很好,但是你没有传递字符串,你传递的是参数的地址。这可以很好地编译,但行为将是未定义的,并且它将取决于取消引用该指针时堆栈上的其他内容。在 Rust 中,编译器会告诉您问题所在,而不是难以调试的问题。

解决方案与 C++ 相同:您需要删除多余的 &amp;,并传递您收到的相同引用:

app.pack_value(&"Data", data);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多