我有一个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(这是我的数据的属性,可以这么说),但这只是避免了问题。
我该怎么办?
答案 0 :(得分:5)
您可以采取以下几种方法:
添加另一层Option
,返回Option<&Option<Foo>>
。我猜你不想这样做。
返回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,
}
}
将合适的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
}
}