如何在Rust Wasm中使用FileReader?
这是我的代码的一部分,REST 移动|事件中的错误:事件|
pub struct FileStream{
el : HtmlInputElement,
}
impl FileStream {
pub fn new(el : HtmlInputElement) -> FileStream {
FileStream {el}
}
pub fn get_file(&self){
let file = self.el.files().unwrap().get(0).unwrap();
let file_reader = FileReader::new().unwrap();
file_reader.read_as_data_url(&file).unwrap();
let onloadend = Closure::wrap(Box::new(move |event: Event| {
let file_reader = file_reader.unchecked_into::<web_sys::FileReader>();
let data_url = file_reader.result().unwrap();
let data_url = data_url.unchecked_into::<JsValue>();
let data_url = data_url.as_string().unwrap();
let audio_el = self.el.unchecked_into::<HtmlAudioElement>();
audio_el.set_src(&data_url);
}) as Box<dyn FnMut(_)>);
file_reader.set_onloadend(Some(onloadend.as_ref().unchecked_ref()));
}
}
我不知道如何修复此错误...
error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
--> src/lib.rs:29:48
|
29 | let onloadend = Closure::wrap(Box::new(move |event: Event| {
| - ^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `FnMut`
| _______________________________________|
| |
30 | | let file_reader = file_reader.unchecked_into::<web_sys::FileReader>();
| | ----------- closure is `FnOnce` because it moves the variable `file_reader` out of its environment
31 | | let data_url = file_reader.result().unwrap();
32 | | let data_url = data_url.unchecked_into::<JsValue>();
... |
35 | | audio_el.set_src(&data_url);
36 | | }) as Box<dyn FnMut(_)>);
| |__________- the requirement to implement `FnMut` derives from here
For more information about this error, try `rustc --explain E0525`.
This is part of my code, the error in rest move |event: Event|
pub struct FileStream{
el : HtmlInputElement,
}
impl FileStream {
pub fn new(el : HtmlInputElement) -> FileStream {
FileStream {el}
}
pub fn get_file(&self){
let file = self.el.files().unwrap().get(0).unwrap();
let file_reader = FileReader::new().unwrap();
file_reader.read_as_data_url(&file).unwrap();
let onloadend = Closure::wrap(Box::new(move |event: Event| {
let file_reader = file_reader.unchecked_into::<web_sys::FileReader>();
let data_url = file_reader.result().unwrap();
let data_url = data_url.unchecked_into::<JsValue>();
let data_url = data_url.as_string().unwrap();
let audio_el = self.el.unchecked_into::<HtmlAudioElement>();
audio_el.set_src(&data_url);
}) as Box<dyn FnMut(_)>);
file_reader.set_onloadend(Some(onloadend.as_ref().unchecked_ref()));
}
}
I don't know how to fix this error...
error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
--> src/lib.rs:29:48
|
29 | let onloadend = Closure::wrap(Box::new(move |event: Event| {
| - ^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `FnMut`
| _______________________________________|
| |
30 | | let file_reader = file_reader.unchecked_into::<web_sys::FileReader>();
| | ----------- closure is `FnOnce` because it moves the variable `file_reader` out of its environment
31 | | let data_url = file_reader.result().unwrap();
32 | | let data_url = data_url.unchecked_into::<JsValue>();
... |
35 | | audio_el.set_src(&data_url);
36 | | }) as Box<dyn FnMut(_)>);
| |__________- the requirement to implement `FnMut` derives from here
For more information about this error, try `rustc --explain E0525`.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
创建闭合时,它将
file_reader
移至自身(因为它被声明为移动||
clos)。然后,当闭合被称为时,它通过调用unchecked_into()
消耗file_reader
。因此,如果要第二次闭合,它将不再具有file_reader
使用。这就是为什么编译器决定关闭只是“fnonce
”的原因。另一方面,
set_onloadend
回调机制需要一个可以多次调用的函数,以防基础事件以不止一次发生。解决此问题的一般解决方案是调整您的功能,以便就编译器而言,可以多次调用 。您可以通过将必须移动的值放在
option
外面,然后使用option :: take()
在闭合中,以将其重新退出 - 因此,如果该功能再次被调用,则将选项
值留为无
。但是,在这种情况下,只需删除整个
unchecked_into()
line会更简单。据我所知,没有必要,因为该对象已经键入filereader
。 (但是我没有尝试编译您的代码来查看它是否没有工作,所以也许我错过了一些东西。)When the closure is created, it moves
file_reader
into itself (because it is declared as amove ||
closure). Then, when the closure is called, it consumesfile_reader
via callingunchecked_into()
. Therefore, if the closure were to be called a second time, it would no longer have afile_reader
to use. That's why the compiler decides the closure is only a “FnOnce
”.On the other hand, the
set_onloadend
callback mechanism wants a function that can be called more than once, in case the underlying event somehow happens more than once.The general solution to this problem is to adjust your function so that it can be called more than once — as far as the compiler is concerned. You can do this by putting the value that must be moved in an
Option
outside the closure, then usingOption::take()
inside the closure to get it back out — thus leaving theOption
value to beNone
if the function ever gets called again.However, in this case, it would be simpler to just remove the entire
unchecked_into()
line. As far as I can see, there is no need for it, because the object is already typed as aFileReader
. (But I haven't tried compiling your code to see if it works without, so maybe I missed something.)