对Rust非常陌生,决定使用Code 2020 Day 1 Puzzle来复习。我使用以下函数:
fn find_numbers_2020(v: Vec<i32>) -> (i32,i32) {
let mut n1: i32 = 0;
let mut n2: i32 = 0;
let mut cnt = 0;
let size = v.len();
for v_i in v {
n1 = v_i;
cnt = cnt+1;
for i in cnt..size {
if (n1 + *v.get(i).unwrap()) == 2020 {
n2 = *v.get(i).unwrap();
(n1, n2) //Issue is here
}
}
}
(n1, n2)
}
但是我得到了错误"32 (n1, n2)
^^^^^^^^ expected (), found tuple.
从main调用,如下所示
fn main() {
let filename = String::from("./input.txt");
let v = parse_file(filename); //This works fine
for v_i in v {
println!("{}", v_i);
}
let result = find_numbers_2020(v);
let (n1, n2) = result;
println!("{} + {} = {}", n1, n2, n1+n2);
println!("{} * {} = {}", n1, n2, n1*n2);
}
我还应该提到v
是Vec<i32>
。对于初学者的问题,很抱歉,但是Rust可能有点令人困惑,我还没有能够通过谷歌找到任何答案。
如果返回值是函数块中的最后一个表达式,则可以省略return
关键字,否则需要显式使用return
。将return
添加到您的示例中可以修复该特定错误,但会出现一堆新错误。我是这样写这个函数的:
fn find_numbers_2020(v: Vec<i32>) -> (i32, i32) {
for (skip, &n1) in v.iter().enumerate() {
for &n2 in v.iter().skip(skip) {
if n1 + n2 == 2020 {
return (n1, n2);
}
}
}
panic!("no pair of numbers in vec sum to 2020");
}
这是需要使用return
表达式的情况之一。您的初始for
循环也消耗v
,因此为了能够在内部循环中执行v.get()
,您需要借用v
代替,即&v
或v.iter()
。
fn find_numbers_2020(v: Vec<i32>) -> (i32, i32) {
let mut n1: i32 = 0;
let mut n2: i32 = 0;
let mut cnt = 0;
let size = v.len();
for &v_i in &v {
n1 = v_i;
cnt = cnt + 1;
for i in cnt..size {
if (n1 + *v.get(i).unwrap()) == 2020 {
n2 = *v.get(i).unwrap();
return (n1, n2);
}
}
}
(n1, n2)
}
这也是可以返回Option
并使用if let
表达式的完美情况。所以不是返回(i32, i32)
,而是返回Option<(i32, i32)>
。
不做*v.get(i).unwrap()
,那么你也可以只索引v
,即v[i]
。
fn find_numbers_2020(v: Vec<i32>) -> Option<(i32, i32)> {
let mut cnt = 0;
for &n1 in &v {
cnt += 1;
for i in cnt..v.len() {
if (n1 + v[i]) == 2020 {
let n2 = v[i];
return Some((n1, n2));
}
}
}
None
}
fn main() {
// ...
if let Some((n1, n2)) = result {
println!("{} + {} = {}", n1, n2, n1 + n2);
println!("{} * {} = {}", n1, n2, n1 * n2);
}
}
您可以在第一个循环中使用enumerate()
,而不是手动增加索引,然后在第二个循环中使用skip(i + 1)
和enumerate()
返回的索引。
fn find_numbers_2020(v: Vec<i32>) -> Option<(i32, i32)> {
for (i, &n1) in v.iter().enumerate() {
for &n2 in v.iter().skip(i + 1) {
if (n1 + n2) == 2020 {
return Some((n1, n2));
}
}
}
None
}
比起v: Vec<i32>
,使用切片(即v: &[i32]
)更为习惯。在main()
中,您只需在find_numbers_2020()
调用中借用v
,即find_numbers_2020(&v)