如何在Rust Wasm中使用FileReader?

发布于 2025-02-05 21:29:48 字数 2170 浏览 1 评论 0原文

这是我的代码的一部分,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独闯女儿国 2025-02-12 21:29:48

创建闭合时,它将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 a move || closure). Then, when the closure is called, it consumes file_reader via calling unchecked_into(). Therefore, if the closure were to be called a second time, it would no longer have a file_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 using Option::take() inside the closure to get it back out — thus leaving the Option value to be None 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 a FileReader. (But I haven't tried compiling your code to see if it works without, so maybe I missed something.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文