正确的锈匹配成语

isp*_*ava 2 recursion switch-statement rust

我意识到语言是0.9/0.10并且仍在进行重大改变(比如do本周下降?),但很想知道我是否在这里使用声音惯用语.我已经实现了两个版本的变更算法,一个是天真的,一个在我看来看起来"更好".

这是0.9.两个片段编译并在一对夫妇得到相同的结果assert!

fn count_change_naive(cents: int, coins: &[int]) -> int {
    if (cents == 0) {
        1
    } else if (cents < 0) {
        0
    } else {
        if coins.iter().len() > 0 {
            let new_amount: int = cents - coins[0];
            let coins_tailed: &[int] = coins.tail();
            count_change_naive(cents, coins_tailed) + count_change_naive(new_amount, coins)
        } else {
            0
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是非常笨拙的IMO.我试图实现以下内容:

fn count_change_idiomatic(cents: int, coins: &[int]) -> int {
    match cents {
        n if cents == 0                     => 1,
        n if cents < 0                      => 0,
        n if coins.iter().len() > 0         => {
            let new_amount: int = cents - coins[0];
            let coins_tailed: &[int] = coins.tail();
            count_change_idiomatic(cents, coins_tailed) + count_change_idiomatic(new_amount, coins)
        },
        _                                   => 0
    }
}
Run Code Online (Sandbox Code Playgroud)

n由于匹配中我得到了未使用的变量警告,但我不确定如何在没有丑陋的if-else金字塔的情况下避免这种情况.可以吗?我错过了第二次实施中的重要内容吗?

编辑:已经清理了一些以满足一些建议,但保持完整的比较

pep*_*ico 5

为了没有得到你没有用的变量的警告,你就是不要使用它:

fn count_change_idiomatic(cents: int, coins: &[int]) -> int {
    match cents {
        _ if cents == 0                     => 1,
        _ if cents < 0                      => 0,
        _ if coins.iter().len() > 0         => {
            let new_amount: int = cents - coins[0];
            let coins_tailed: &[int] = coins.tail();
            count_change_idiomatic(cents, coins_tailed) + count_change_idiomatic(new_amount, coins)
        },
        _                                   => 0
    }
}
Run Code Online (Sandbox Code Playgroud)


huo*_*uon 5

您可以在向量上使用模式匹配来避免长度,索引和拖尾:

fn count_change_idiomatic(cents: int, coins: &[int]) -> int {
    match (cents, coins) {
        (0, _)                        => 1,
        _ if cents < 0                => 0,
        (_, [first, .. coins_tailed]) => {
            let new_amount = cents - first;
            count_change_idiomatic(cents, coins_tailed) + 
                count_change_idiomatic(new_amount, coins)
        }
        _                             => 0
    }
}
Run Code Online (Sandbox Code Playgroud)

..模式的一部分与向量的其余部分匹配(在这种情况下,除了第一个元素之外的所有内容).