如何从一个借用它的论证的函数中返回None,或者避免需要?

时间:2015-04-25 07:13:04

标签: rust

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

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

我经常需要这样做,所以返回&Option<Foo>的函数似乎是合适的,添加了一个生命周期说明符,因为很明显返回值不应该超过它借来的切片。这导致我:

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(这是我的数据的属性,可以这么说),但这只是避免了问题。

我该怎么办?

2 个答案:

答案 0 :(得分:5)

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

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

  2. 返回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存储为静态并返回对它的引用。它的生命周期为'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)
    }
    

答案 1 :(得分:4)

由于您显然不需要通过此功能改变切片,因此可以选择将返回类型从&'a Option<Foo>切换为Option<&'a Foo>。这样,您在返回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
    }
}