我意识到语言是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
}
}
}
这是非常笨拙的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
}
}
由于匹配中的n
,我得到了未使用的变量警告,但我不确定如何在没有丑陋的if-else金字塔的情况下避免这种情况。可以吗?我在第二次实施中遗漏了哪些重要内容?
答案 0 :(得分: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
}
}
答案 1 :(得分: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
}
}
模式的..
部分与向量的其余部分匹配(在这种情况下,除了第一个元素之外的所有部分)。
答案 2 :(得分:2)
这是对事物的重大简化,改进各种惯用事物:
fn count_change_naive(cents: int, coins: &[int]) -> int {
if cents == 0 {
1
} else if cents < 0 {
0
} else if coins.len() > 0 {
let new_amount = cents - coins[0];
let denom_tailed = coins.tail();
count_change_naive(cents, denom_tailed) + count_change_naive(new_amount, coins)
} else {
0
}
}
return
; if
陈述if
/ else
内容的嵌套(else { if A { B } else { C } }
→else if A { B } else { C }
)我用适当的信息做出了另一个改变:自由评论事物的意义。可能甚至将递归调用转移到它们自己的语句中(这通常会增强可读性并且没有运行时成本):
let ???1 = count_change_naive(cents, demon_tailed);
let ???2 = count_change_naive(new_amount, coins);
???1 + ???2