如何在数组、向量或切片中找到元素的索引?

153

我需要在一个字符串向量中找到一个元素的索引。目前我有以下代码:

fn main() {
    let test: Vec<String> = vec![
        "one".to_string(),
        "two".to_string(),
        "three".to_string(),
        "four".to_string(),
    ];

    let index: i32 = test
        .iter()
        .enumerate()
        .find(|&r| r.1.to_string() == "two".to_string())
        .unwrap()
        .0;
}

它会产生一个错误:

error[E0308]: mismatched types
  --> src/main.rs:9:22
   |
9  |       let index: i32 = test
   |  ______________________^
10 | |         .iter()
11 | |         .enumerate()
12 | |         .find(|&r| r.1.to_string() == "two".to_string())
13 | |         .unwrap()
14 | |         .0;
   | |__________^ expected i32, found usize
我认为这是因为enumerate()返回一个元组(usize, _)(如果我错了请纠正),但是在这里该如何将usize转换为i32?如果有更好的方法,我也愿意听取建议。
2个回答

253

我认为你应该查看position方法。

fn main() {
    let test = vec!["one", "two", "three"];
    let index = test.iter().position(|&r| r == "two").unwrap();
    println!("{}", index);
}

您可以在此处进行测试

请注意,这适用于任何迭代器,因此它可用于向量、数组和切片,所有这些都会生成迭代器。


1
|r| *r == target 或者我得到了“无法移动共享引用”的错误信息。 - Russo

73
TLDR 使用带有 position 方法的迭代器,Rust文档中有很好的示例
不,这是因为索引是 usize,而不是 i32。实际上,i32 完全不适合此目的;它可能不够大,并且没有理由让它成为有符号数。只需使用 usize 即可。
其他一些注意事项:调用 to_string() 不是免费的,而且你不需要它来进行比较;你可以很好地比较字符串切片!
另外,如果你真的想将 usize 转换为 i32,你可以使用强制类型转换: x as i32,但这将不会产生溢出或下溢错误(即结果可能为负数)。
总之,正如 Mathieu David 的答案中所指出的那样,在迭代器上有一个position方法可以做到你想要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接