gpt4 book ai didi

rust - 从Rust中的WebAssembly中的Window对象获取查询字符串

转载 作者:行者123 更新时间:2023-12-03 11:35:39 25 4
gpt4 key购买 nike

上下文:我正在学习Rust和WebAssembly,作为一个练习,我有一个项目可以从Rust代码中绘制HTML Canvas中的内容。我想从Web请求中获取查询字符串,然后代码可以确定要调用哪个绘图函数。

我编写此函数只是返回删除了开头的?的查询字符串:

fn decode_request(window: web_sys::Window) -> std::string::String {
let document = window.document().expect("no global window exist");
let location = document.location().expect("no location exists");
let raw_search = location.search().expect("no search exists");
let search_str = raw_search.trim_start_matches("?");
format!("{}", search_str)
}

它确实可以工作,但是考虑到我使用的其他一些语言要简单得多,它似乎太冗长了。

有没有更简单的方法可以做到这一点?还是冗长的话仅仅是您为Rust的安全付出的代价,我应该习惯它吗?

根据@IInspectable 的每个答案进行编辑:
我尝试了链接方法,但出现以下错误:
temporary value dropped while borrowed

creates a temporary which is freed while still in use

note: consider using a `let` binding to create a longer lived value rustc(E0716)

更好地了解这一点是很高兴的。我仍然在脑海里浮现出所有权的精妙之处。就是现在:

fn decode_request(window: Window) -> std::string::String {
let location = window.location();
let search_str = location.search().expect("no search exists");
let search_str = search_str.trim_start_matches('?');
search_str.to_owned()
}

这当然是一个进步。

最佳答案

这个问题实际上是关于API设计的,而不是它对实现的影响。事实证明,该实现相当冗长,主要是由于选择了契约(Contract):产生值(value),否则就死掉。这份契约(Contract)天生没有错。调用此函数的客户端将永远不会观察到无效数据,因此这是绝对安全的。

但是,这可能不是库代码的最佳选择。库代码通常缺少上下文,并且无法很好地判断任何给定的错误情况是否致命。这是一个客户代码可以更好地回答的问题。

在继续探索替代方案之前,让我们以更紧凑的方式重写原始代码,方法是将调用链接在一起,而无需将每个结果显式分配给变量:

fn decode_request(window: web_sys::Window) -> std::string::String {
window
.location()
.search().expect("no search exists")
.trim_start_matches('?')
.to_owned()
}

我不熟悉 web_sys crate ,因此涉及一些猜测工作。即,假设 window.location()返回与 document()location()相同的值。除了链接调用之外,所提供的代码还进行了另外两项更改:
  • trim_start_matches()传递了字 rune 字代替字符串文字。这将产生最佳代码,而无需依赖编译器的优化器来确定长度为1的字符串正在尝试搜索单个字符。
  • 通过调用to_owned()构造返回值。 format!宏会增加开销,并最终调用to_string()。虽然在这种情况下会表现出相同的行为,但是使用语义上更准确的to_owned()函数可以帮助您在编译时捕获错误(例如,如果您意外返回42.to_string())。

  • 备择方案

    实现此功能的更自然的方法是让它返回代表查询字符串的值,或者根本不返回任何值。 Rust提供了 Option 类型来方便地对此建模:

    fn decode_request(window: web_sys::Window) -> Option<String> {
    match window
    .location()
    .search() {
    Ok(s) => Some(s.trim_start_matches('?').to_owned()),
    _ => None,
    }
    }

    这允许函数的客户根据函数返回 Some(s)还是 None来做出决定。这会将所有错误条件映射到 None值。

    如果希望将失败原因传达回调用者, decode_request函数可以选择返回 Result 值,例如 Result<String, wasm_bindgen::JsValue>。这样,实现可以利用 ?运算符以紧凑的方式将错误传播给调用方:

    fn decode_request(window: web_sys::Window) -> Result<String, wasm_bindgen::JsValue> {
    Ok(window
    .location()
    .search()?
    .trim_start_matches('?')
    .to_owned())
    }

    关于rust - 从Rust中的WebAssembly中的Window对象获取查询字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61562461/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com