【发布时间】:2018-10-12 12:14:16
【问题描述】:
作为 Rust 新手,我正在解决 Project Euler 问题以帮助我了解该语言。问题 4 涉及回文,我找到了两种创建回文向量的解决方案,但我不确定它们是如何工作的。
我使用的是字符串向量products,其计算方式如下:
let mut products = Vec::new();
for i in 100..500 {
for j in 500..1000 {
products.push((i * j).to_string());
}
}
为了将这些产品过滤到只有回文的产品,我有以下两种解决方案:
解决方案 1:
let palindromes: Vec<_> = products
.iter()
.filter(|&x| x == &x.chars().rev().collect::<String>())
.collect();
解决方案 2:
let palindromes: Vec<_> = products
.iter()
.filter(|&x| *x == *x.chars().rev().collect::<String>())
.collect();
它们都产生了正确的结果,但我不知道为什么!
在解决方案 1 中,我们将字符串的引用与我们刚刚创建的字符串的引用进行比较?
在解决方案 2 中,我们取消引用对字符串的引用并将其与取消引用的新字符串进行比较?
我希望能够做到的事情:
let palindromes: Vec<_> = products
.iter()
.filter(|x| x == x.chars().rev().collect::<String>())
.collect();
希望有人能给我解释一下:
- 我的两种解决方案有什么区别,为什么它们都有效?
- 为什么我不能只使用
x而不在我的过滤器函数中引用或取消引用它?
谢谢!
【问题讨论】:
-
"它们都产生了正确的结果,但我不知道为什么!" => “理论是你什么都知道,但没有人知道为什么实践是一切都有效,但没有人知道为什么在我们的实验室中,理论和实践相结合,没有人知道为什么”
-
我认为这与How to iterate over an array? 非常相似(尽管标题很差)。这个问题的答案是否清楚?
-
注意不需要分配
String,可以比较迭代器:.filter(|x| x.chars().eq(x.chars().rev()))。 -
@piercebot 很好,Project Euler 也是我开始 rust 的方式。我可以挑战你提出一个不需要分配的回文检查(
collect在堆上创建一个新的String)吗? :) -
嗯.. 挑战太多了:p
标签: string rust dereference borrowing