【问题标题】:Is there a way to simplify the access to an inner functionality of web_sys?有没有办法简化对 web_sys 内部功能的访问?
【发布时间】:2020-10-12 15:54:10
【问题描述】:

阅读 Rust 书后,我决定尝试使用 Web Assembly。我正在创建一个简单的跟踪器脚本来练习和了解更多信息。有几个方法需要访问窗口、导航器或 cookie API。每次我必须访问其中任何一个时,都会涉及很多样板代码:

pub fn start() {
        let window = web_sys::window().unwrap();
        let document = window.document().unwrap();
        let html = document.dyn_into::<web_sys::HtmlDocument>().unwrap();
        let cookie = html_document.cookie().unwrap();
}

这是不切实际的,让我很困扰。有没有聪明的方法来解决这个问题?事实上,我已经尝试使用lazy_static 将所有这些都放在global.rs 文件中:

#[macro_use]
extern crate lazy_static;

use web_sys::*;

lazy_static! {
    static ref WINDOW: window = {
        web_sys::window().unwrap()
    };
}

但编译失败:*mut u8 不能在线程之间安全共享。

【问题讨论】:

  • 什么都没有?真的吗?
  • 只使用函数? fn html() -&gt; HtmlDocument {let window = web_sys::window().unwrap(); let document = window.document().unwrap(); document.dyn_into::&lt;web_sys::HtmlDocument&gt;().unwrap()}
  • 一点补充:在任何地方都使用 unwrap 可能是一种不好的做法。尝试处理错误,或者至少使用 .expect(),这样您就可以提供有意义的错误消息,而不是 tried calling unwrap on...

标签: rust global-variables webassembly


【解决方案1】:

您可以使用? 运算符而不是展开。

而不是写

pub fn start() {
  let window = web_sys::window().unwrap();
  let document = window.document().unwrap();
  let html = document.dyn_into::<web_sys::HtmlDocument>().unwrap();
  let cookie = html_document.cookie().unwrap();
}

你可以写

pub fn start() -> Result<()> {
  let cookie = web_sys::window()?
                 .document()?
                 .dyn_into<web_sys::HtmlDocument>()?
                 .cookie()?;
  Ok(())
}

它的行数相同,但样板更少,对于更简单的情况是单行。

如果您真的不想返回结果,您可以将整个内容包装在 lambda 中(如果您喜欢使用不稳定的功能,则可以使用 try 块)。

pub fn start() {
  let cookie = (|| Result<Cookie)> {
    web_sys::window()?
      .document()?
      .dyn_into<web_sys::HtmlDocument>()?
      .cookie()
   }).unwrap();
}

如果您不喜欢经常重复此操作 - 您可以使用函数

fn document() -> Result<Document> {
  web_sys::window()?.document()
}

fn html() -> Result<web_sys::HtmlDocument> {
  document()?.dyn_into<web_sys::HtmlDocument>()
}

fn cookie() -> Result<Cookie> {
  html()?.cookie()
}

pub fn start() {
  let cookie = cookie()?;
}

【讨论】:

    【解决方案2】:

    这不切实际,让我很困扰。

    不确定您的问题是什么,但是如果您在应用程序中一次又一次地访问同一个 cookie,也许您可​​以将它保存在一个结构中并直接使用该结构?在我最近的 WebAssembly 项目中,我保存了一些我在结构中使用过的元素,并通过传递它来使用它们。

    我还认为,也许解释您的具体用例可能会导致更具体的答案:)

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      • 2018-11-08
      相关资源
      最近更新 更多