我的生命周期出现锈编译错误

时间:2019-08-29 07:01:01

标签: rust lifetime

我正在尝试编译一些rust代码,但是我不断收到有关类型和生存期的错误。谁能解释我在做什么错?

我在编译时遇到错误:associated type bindings must be declared after generic parameters。我想我已经尝试了所有参数组合,但似乎都不起作用。

这是我的代码的简化版本。

/*! test of lifetimes for compile */
extern crate web_view;
use web_view::*;
struct UserData {}

type TestResult = WVResult<i64>;
type TestView = WebView<UserData>;
type TestBuilder<'a> = WebViewBuilder< UserData: 'a,'a, 
         FnMut(&mut TestView, &str) -> TestResult, String>; // compile error

fn main() {
    let mut p = UserData {};
    let wvb: TestBuilder = WebViewBuilder::new();
    let mut webview: TestView = wvb
        .title("Progress")
        .content("hello")
        .size(640, 960)
        .resizable(true)
        .debug(false)
        .user_data(p)
        .invoke_handler(handler)
        .build()
        .unwrap();
    let _res = webview.run().unwrap();
}
fn handler(webview: &mut TestView, arg: &str) -> TestResult {
    Ok(1)
}

这应该是注释,但是太长了,无法放入注释中。我使用了@zizka的答案,但恢复了TestResult的原始版本。现在,我收到以下错误消息:“未找到功能或相关项目”和“未找到类型的名为title的方法”

use web_view::*;

struct UserData {}

type TestResult = WVResult<i64>;
type TestView<'a> = WebView<'a, UserData>;
type TestBuilder<'a> =
    WebViewBuilder<'a, UserData, fn(&mut TestView, &str) -> TestResult, &'static str>;

fn main() {
    let p = UserData {};

    let builder: TestBuilder = TestBuilder::new(); // error here
    let webview = builder
        .title("Progress") // error here
        .content(Content::Url("https://en.m.wikipedia.org/wiki/Main_Page"))
        .size(640, 960)
        .resizable(true)
        .debug(false)
        .user_data(p)
        .invoke_handler(handler)
        .build()
        .unwrap();
    webview.run().unwrap();
}

fn handler(_webview: &mut TestView, _arg: &str) -> TestResult {
    Ok(17 as i64)
}

1 个答案:

答案 0 :(得分:2)

问题

TestView

您的定义:

type TestView = WebView<UserData>;

WebView定义为:

pub struct WebView<'a, T: 'a> {
    inner: *mut CWebView,
    _phantom: PhantomData<&'a mut T>,
}

它期望生存期和T,生存期必须与生存期一样长。固定定义:

type TestView<'a> = WebView<'a, UserData>;

TestBuilder

您的定义:

type TestBuilder<'a> = WebViewBuilder< UserData: 'a,'a, 
         FnMut(&mut TestView, &str) -> TestResult, String>;

WebViewBuilder定义为:

pub struct WebViewBuilder<'a, T: 'a, I, C>
    pub title: &'a str,
    pub content: Option<Content<C>>,
    pub width: i32,
    pub height: i32,
    pub resizable: bool,
    pub debug: bool,
    pub invoke_handler: Option<I>,
    pub user_data: Option<T>,
}
  • 'a生命周期必须排在第一位,UserData之后是生命周期
  • UserData预期寿命-> UserData<'a>,而不是UserData: 'a
  • FnMut(...)是一个特征,它的大小在编译时未知,您必须用Box包装它,使用fn,...
  • C在您的情况下是String,这意味着您不能使用.content("hello"),因为a)它期望Content<C>,b)即使您使用Content::Html("hello")无效,因为它是Content<&'static str>,并且您说过要Content<String>-> Content::Html("hello".to_string())

固定定义:

type TestBuilder<'a> =
    WebViewBuilder<'a, UserData, Box<dyn FnMut(&mut TestView, &str) -> TestResult>, String>;

WebViewBuilder

但是,即使您修复了所有这些问题,它也无法正常工作。查看WebViewBuilder的实现:

impl<'a, T: 'a, I, C> Default for WebViewBuilder<'a, T, I, C>
where
    I: FnMut(&mut WebView<T>, &str) -> WVResult + 'a,
    C: AsRef<str>
{...}
impl<'a, T: 'a, I, C> WebViewBuilder<'a, T, I, C>
where
    I: FnMut(&mut WebView<T>, &str) -> WVResult + 'a,
    C: AsRef<str>,
{...}

特别是这一行:

I: FnMut(&mut WebView<T>, &str) -> WVResult + 'a

它期望WVResult(-> Result<(), Error>),这意味着您不能使用TestResult(-> WVResult<i64>-> Result<i64, Error>) 。源代码中没有其他实现。

一个例子

工作代码,它确实使用您的类型,但是TestResult只是WVResulti64-> ())。

use web_view::*;

struct UserData {}

type TestResult = WVResult;

type TestView<'a> = WebView<'a, UserData>;

type TestBuilder<'a> =
    WebViewBuilder<'a, UserData, Box<dyn FnMut(&mut TestView, &str) -> TestResult>, String>;

fn main() {
    let p = UserData {};

    let wvb: TestBuilder = WebViewBuilder::new();
    let webview: TestView = wvb
        .title("Progress")
        .content(Content::Url(
            "https://en.m.wikipedia.org/wiki/Main_Page".to_string(),
        ))
        .size(640, 960)
        .resizable(true)
        .debug(false)
        .user_data(p)
        .invoke_handler(Box::new(handler))
        .build()
        .unwrap();
    let _res = webview.run().unwrap();
}

fn handler(_webview: &mut TestView, _arg: &str) -> TestResult {
    Ok(())
}