当前位置:  开发笔记 > 后端 > 正文

用于字符串的Rust中F#的Cons模式的等价

如何解决《用于字符串的Rust中F#的Cons模式的等价》经验,为你挑选了1个好方法。

我正在通过实现我的一个小F#片段来试验Rust.

我正处于想要构造一串字符的地步.这是F#:

 let rec internalCheck acc = function
    | w :: tail when Char.IsWhiteSpace(w) -> 
        internalCheck acc tail
    | other
    | matches
    | here

..这可以称得上是这样的:internalCheck [] "String here"::运营商表示右手边是"列表中的其余部分."

所以我检查了Rust文档,并且有像这样的解构向量的示例:

let v = vec![1,2,3];

match v {
    [] => ...
    [first, second, ..rest] => ...
}

..等等.然而,现在这是slice_patterns功能门的背后.我尝试过类似的东西:

match input.chars() {
    [w, ..] => ...
}

这告诉我功能门需要使用非稳定版本.

所以我下载multirust并安装了最新的夜间我可以找到(2016-01-05),当我最终使slice_patterns功能工作时...我遇到了无法解决的语法错误和"休息"(在上面的例子中)不被允许.

那么,是否有一种等效的方法来构造一串字符,利用::类似于Rust的功能...... 基本上我想将1个角色与守卫相匹配,并在随后的表达式中使用"其他所有内容".

如果答案是"不,没有",这是完全可以接受的.我当然无法在任何地方在线找到这种类型的许多示例,并且切片模式匹配在功能列表上似乎并不高.

(如果在Rust文档中遗漏了一些内容,我将很乐意删除此问题)



1> ArtemGr..:

您可以使用与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()));
    }
}

您可以将它与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::>()));
    }
}

但截至目前,它不适用于&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));
    }
}

您还可以使用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));
    }
}

但请记住,截至目前,Rust无法保证将此尾递归函数优化为循环.(尾部调用优化将成为该语言的一个受欢迎的补充,但由于与LLVM相关的困难,它迄今尚未实现).

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有