从Rust中WebAssembly中的窗口对象获取查询字符串
背景:我正在学习Rust&WebAssembly,作为一个实践练习,我有一个项目,用Rust代码在HTML画布上绘制东西。我想从web请求中获取查询字符串,然后代码可以从中决定调用哪个绘图函数 我编写此函数只是为了返回前导从Rust中WebAssembly中的窗口对象获取查询字符串,rust,wasm-bindgen,rust-wasm,Rust,Wasm Bindgen,Rust Wasm,背景:我正在学习Rust&WebAssembly,作为一个实践练习,我有一个项目,用Rust代码在HTML画布上绘制东西。我想从web请求中获取查询字符串,然后代码可以从中决定调用哪个绘图函数 我编写此函数只是为了返回前导?已删除的查询字符串: fn解码请求(窗口:web\u系统::窗口)->std::string::string{ 让document=window.document().expect(“不存在全局窗口”); 让location=document.location().expec
?
已删除的查询字符串:
fn解码请求(窗口:web\u系统::窗口)->std::string::string{
让document=window.document().expect(“不存在全局窗口”);
让location=document.location().expect(“不存在位置”);
让raw_search=location.search().expect(“不存在搜索”);
让search\u str=raw\u search.trim\u start\u匹配(“?”);
格式!(“{}”,搜索)
}
它确实能工作,但考虑到在我使用过的其他一些语言中它会变得简单得多,它似乎令人惊讶地冗长
有没有更简单的方法?还是说这种冗长只是你为生锈的安全付出的代价,我应该习惯它
从@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解码请求(窗口:窗口)->std::string::string{
让location=window.location();
让search_str=location.search().expect(“不存在搜索”);
让search_str=search_str.trim_start_匹配(“?”);
搜索街到所有的()
}
这当然是一个改进。这个问题实际上是关于API设计,而不是它对实现的影响。实现结果相当冗长,主要是因为选择了契约:要么产生价值,要么死亡。这份合同本身没有什么问题。调用此函数的客户端永远不会观察到无效数据,因此这是完全安全的 不过,这可能不是库代码的最佳选择。库代码通常缺少上下文,并且不能很好地调用任何给定的错误条件是否是致命的。这是一个客户机代码更好回答的问题 在继续探索替代方案之前,让我们以更紧凑的方式重写原始代码,将调用链接在一起,而不显式地将每个结果分配给变量:
fn解码请求(窗口:web\u系统::窗口)->std::string::string{
窗口
.地点()
.search().expect(“不存在搜索”)
.trim_start_匹配(“?”)
.to_拥有()
}
我不熟悉web\u sys
板条箱,因此有一些猜测。也就是说,假设window.location()
返回的值与document()
的location()的值相同。除了链接调用之外,本文介绍的代码还进行了两项更改:
trim\u start\u matches()
被传递一个字符文本来代替字符串文本。这将生成最佳代码,而无需依赖编译器的优化器来确定长度为1的字符串正在尝试搜索单个字符
- 返回值是通过调用
到_owned()
来构造的。格式代码>宏增加了开销,最终调用到\u string()
。虽然在本例中也会表现出相同的行为,但使用语义更准确的to_owned()
函数可以帮助您在编译时捕获错误(例如,如果您意外地将42.to_string()
)
选择
实现此函数更自然的方法是让它返回表示查询字符串的值,或者根本不返回任何值。Rust提供了方便建模的类型:
fn解码请求(窗口:web\u系统::窗口)->选项{
匹配窗口
.地点()
.search(){
Ok(s)=>一些(s.trim_start_匹配(“?”)。到_owned()),
_=>没有,
}
}
这允许函数的客户端根据函数返回的是Some(s)
还是None
做出决定。这将所有错误条件映射为None
值
如果需要将故障原因反馈给调用者,则解码请求
函数可以选择返回一个值,例如结果
。在这样做时,实现可以利用?
操作符,以紧凑的方式将错误传播给调用方:
fn解码请求(窗口:web\u sys::window)->结果{
好的(窗口
.地点()
.search()?
.trim_start_匹配(“?”)
.to_owned())
}
谢谢,反馈很好。当我尝试纯链接方法时出现的附加错误。如果你想到了这一点,那就太好了,但不管怎样,你的回答已经很有帮助了search().unwrap()
返回一个从未分配给变量的字符串;它的生存期在语句末尾结束,但是trim\u start\u matches
返回一个切片引用,该切片引用比临时引用更有效。我将更新答案以解决此问题。在更新的代码中,trim\u start\u matches
仍将切片引用返回到临时字符串中。改变的是切片引用本身现在是临时的。它的生命结束与它的引用对象,即临时字符串
值的生命结束一致。现在再也没有机会创建一个悬空的引用,借阅检查器也高兴了。谢谢。Rust处理大多数语言数据的作用域/生存期的方式不同,这肯定是我仍在努力解决的问题。@mat life仅限于封闭的作用域。这是一个相当传统的选择,与许多编程语言共享。事实上,如果你有机会,你也会遇到同样的人生问题。Rust的独特之处在于它在c