我正在尝试编译一些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)
}
答案 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
只是WVResult
(i64
-> ()
)。
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(())
}