我怎样才能 return None 从一个借用它的参数的函数中,或者避免需要这样做?

How can I return None from a function that borrows from it's argument, or avoid needing to?

我有一个 Option 切片,并给定一个值,如果该值是切片中的有效索引,我想使用该索引处的值,否则使用 None.

现在,值需要能够被重用,所以我想我想从我的切片中借用,而不是移动...请注意 Foo 没有实现 Copy 特性和我宁愿保持这种状态。

我需要经常这样做,所以函数 returning &Option<Foo> 似乎是合适的,加上生命周期说明符,因为显然 return 值不应该比slice 是借来的。这让我想到:

fn get_or_none<'a>(data: &'a [Option<Foo>], bar: u8) -> &'a Option<Foo> {
  match bar as usize {
    idx if idx < data.len() => &data[idx],
    _ => &None // obviously can't work
  }
}

这显然是错误的。我现在可以作弊,因为我知道对于这个特定的应用程序,切片中的第一个值将始终是 None(可以这么说,它是我数据的 属性),但这只是避免了问题。

我应该怎么做?

由于您显然不需要通过此函数改变切片,因此另一种方法是将 return 类型从 &'a Option<Foo> 切换为 Option<&'a Foo>。这样,您 returning None.

就不会有任何问题

为此,您可以使用 Option::as_ref(..) 方法,该方法允许您将 &Option<Foo> 变成 Option<&Foo>

最后,你有:

fn get_or_none<'a>(data: &'a [Option<Foo>], bar: u8) -> Option<&'a Foo> {
    match bar as usize {
        idx if idx < data.len() => data[idx].as_ref(),
        _ => None
    }
}

您可以采取以下几种方法:

  1. 添加另一层 Optionness,returning 一个 Option<&Option<Foo>>。我猜你不想这样做。

  2. Return 一个 Option<&Foo> 而不是 &Option<Foo>:

    fn get_or_none(data: &[Option<Foo>], bar: u8) -> Option<&Foo> {
        match data.get(bar as usize) {
            Some(&Some(ref foo)) => Some(foo),
            _ => None,
        }
    }
    
  3. 将合适的 None 存储为静态并 return 对其进行引用。它的生命周期是 'static(只要 Foo'static),所以对它的引用可以缩短到 'a 没有问题。

    static NO_FOO: Option<Foo> = None;
    
    fn get_or_none(data: &[Option<Foo>], bar: u8) -> &Option<Foo> {
        data.get(bar as usize).unwrap_or(&NO_FOO)
    }