在Rust函数调用上键入提示

时间:2016-09-07 00:54:18

标签: rust

我正在尝试从结构中提取函数。原始(工作)是:

\b(is|small)\b

pub fn f(&self, id: Id) -> &[Foo] { self.foos.get(&id).map_or(&[], |foos| &**foos) } self.foos

的位置

提取后我有

HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>

产生的错误是

fn f<'a>(foos: HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &'a [Foo] {
    &foos.get(&id).map_or(&[], |xs| &**xs);
}

我想我需要提供一个类型提示。这是正确的吗?如果是这样,我如何在调用error: mismatched types: expected `&[_; 0]`, found `&[foo::Foo]` (expected array of 0 elements, found slice) [E0308]

时明确声明U的类型

1 个答案:

答案 0 :(得分:7)

您遇到的错误会隐藏代码的实际问题。在这种情况下,通过更明确,编译器可以进一步提供与解决问题更相关的其他错误。

首先,让我们通过将&[]更改为&[][..]将数组显式转换为切片来消除类型不匹配。

fn f<'a>(foos: HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &'a [Foo] {
    &foos.get(&id).map_or(&[][..], |xs| &**xs);
}

我们现在收到此错误:

error: not all control paths return a value [--explain E0269]
  --> <anon>:16:1
   |>
16 |> fn f<'a>(foos: HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &'a [Foo] {
   |> ^
啊哈哈!函数末尾有一个分号,不应该在那里。我们将其删除。

fn f<'a>(foos: HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &'a [Foo] {
    &foos.get(&id).map_or(&[][..], |xs| &**xs)
}
嗯,还是没有编译:

error: `foos` does not live long enough
  --> <anon>:17:6
   |>
17 |>     &foos.get(&id).map_or(&[][..], |xs| &**xs)
   |>      ^^^^
note: reference must be valid for the lifetime 'a as defined on the block at 16:90...
  --> <anon>:16:91
   |>
16 |> fn f<'a>(foos: HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &'a [Foo] {
   |>                                                                                           ^
note: ...but borrowed value is only valid for the scope of function body at 16:90
  --> <anon>:16:91
   |>
16 |> fn f<'a>(foos: HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &'a [Foo] {
   |>                                                                                           ^

基本上,错误是您尝试将借用的指针返回到HashMap,该f将在HashMap调用结束时被销毁(因为HashMap }按值传递)。您需要通过引用传递[..]。我们现在可以摆脱不必要的fn f(foos: &HashMap<Id, Vec<Foo>, BuildHasherDefault<FnvHasher>>, id: Id) -> &[Foo] { foos.get(&id).map_or(&[], |xs| &**xs) } 因为它编译了!

list_of_attributes = ["a1", "a2", "a3", "a4"]
user_selections = ["a2", "a4"]