我在生命周期中遇到生锈编译错误
I am getting a rust compile error with lifetimes
我正在尝试编译一些 Rust 代码,但我不断收到有关类型和生命周期的错误。谁能解释我做错了什么?
我在编译时遇到错误:associated type bindings must be declared after generic parameters
。我已经尝试过,我认为,参数的所有组合和它们的 none 似乎都有效。
这是我的代码的简化版本。
/*! 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。现在我收到 "function or associated item not found" 和 "no method named title
found for type"
的错误
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)
}
问题
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
lifetime必须在前,你有在UserData
之后
UserData
期望生命周期 -> UserData<'a>
,而不是 UserData: 'a
FnMut(...)
是一个trait,意思是编译时不知道大小,得用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(())
}
我正在尝试编译一些 Rust 代码,但我不断收到有关类型和生命周期的错误。谁能解释我做错了什么?
我在编译时遇到错误:associated type bindings must be declared after generic parameters
。我已经尝试过,我认为,参数的所有组合和它们的 none 似乎都有效。
这是我的代码的简化版本。
/*! 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。现在我收到 "function or associated item not found" 和 "no method named title
found for type"
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)
}
问题
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
lifetime必须在前,你有在UserData
之后
UserData
期望生命周期 ->UserData<'a>
,而不是UserData: 'a
FnMut(...)
是一个trait,意思是编译时不知道大小,得用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(())
}