我正在通过实现我的一个小F#片段来试验Rust.
我正处于想要构造一串字符的地步.这是F#:
let rec internalCheck acc = function
| w :: tail when Char.IsWhiteSpace(w) ->
internalCheck acc tail
| other
| matches
| here
Run Code Online (Sandbox Code Playgroud)
..这可以称得上是这样的:internalCheck [] "String here"当::运营商表示右手边是"列表中的其余部分."
所以我检查了Rust文档,并且有像这样的解构向量的示例:
let v = vec![1,2,3];
match v {
[] => ...
[first, second, ..rest] => ...
}
Run Code Online (Sandbox Code Playgroud)
..等等.然而,现在这是slice_patterns功能门的背后.我尝试过类似的东西:
match input.chars() {
[w, ..] => ...
}
Run Code Online (Sandbox Code Playgroud)
这告诉我功能门需要使用非稳定版本.
所以我下载multirust并安装了最新的夜间我可以找到(2016-01-05),当我最终使slice_patterns功能工作时...我遇到了无法解决的语法错误和"休息"(在上面的例子中)不被允许.
那么,是否有一种等效的方法来构造一串字符,利用::类似于Rust的功能...... 基本上我想将1个角色与守卫相匹配,并在随后的表达式中使用"其他所有内容".
如果答案是"不,没有",这是完全可以接受的.我当然无法在任何地方在线找到这种类型的许多示例,并且切片模式匹配在功能列表上似乎并不高.
(如果在Rust文档中遗漏了一些内容,我将很乐意删除此问题)
您可以使用与byte切片匹配的模式:
#![feature(slice_patterns)]
fn internal_check(acc: &[u8]) -> bool {
match acc {
&[b'-', ref tail..] => internal_check(tail),
&[ch, ref tail..] if (ch as char).is_whitespace() => internal_check(tail),
&[] => true,
_ => false,
}
}
fn main() {
for s in ["foo", "bar", " ", " - "].iter() {
println!("text '{}', checks? {}", s, internal_check(s.as_bytes()));
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将它与char切片一起使用(其中char是Unicode标量值):
#![feature(slice_patterns)]
fn internal_check(acc: &[char]) -> bool {
match acc {
&['-', ref tail..] => internal_check(tail),
&[ch, ref tail..] if ch.is_whitespace() => internal_check(tail),
&[] => true,
_ => false,
}
}
fn main() {
for s in ["foo", "bar", " ", " - "].iter() {
println!("text '{}', checks? {}",
s, internal_check(&s.chars().collect::<Vec<char>>()));
}
}
Run Code Online (Sandbox Code Playgroud)
但截至目前,它不适用于&str(生产E0308).我认为这是最好的&str,既不是在这里,也不是在那里,它是一个byte片层,但Rust试图保证它是一个有效的UTF-8并试图提醒你使用&strunicode序列和字符而不是字节.所以为了有效地匹配&str我们必须明确地使用这个as_bytes方法,基本上告诉Rust"我们知道我们在做什么".
无论如何,这是我的阅读.如果您想深入挖掘Rust编译器的源代码,可以从问题1844开始,浏览那里链接的提交和问题.
基本上我想将1个角色与守卫相匹配,并在随后的表达式中使用"其他所有内容".
如果您只想匹配单个字符,那么使用字符迭代器获取字符并匹配字符本身可能比将整个UTF-8 &str转换为&[char]切片更好.例如,使用chars迭代器,您不必为characters数组分配内存.
fn internal_check(acc: &str) -> bool {
for ch in acc.chars() {
match ch {
'-' => (),
ch if ch.is_whitespace() => (),
_ => return false,
}
}
return true;
}
fn main() {
for s in ["foo", "bar", " ", " - "].iter() {
println!("text '{}', checks? {}", s, internal_check(s));
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用chars迭代器来拆分&strUnicode标量值边界:
fn internal_check(acc: &str) -> bool {
let mut chars = acc.chars();
match chars.next() {
Some('-') => internal_check(chars.as_str()),
Some(ch) if ch.is_whitespace() => internal_check(chars.as_str()),
None => true,
_ => false,
}
}
fn main() {
for s in ["foo", "bar", " ", " - "].iter() {
println!("text '{}', checks? {}", s, internal_check(s));
}
}
Run Code Online (Sandbox Code Playgroud)
但请记住,截至目前,Rust无法保证将此尾递归函数优化为循环.(尾部调用优化将成为该语言的一个受欢迎的补充,但由于与LLVM相关的困难,它迄今尚未实现).
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |