Expand description
添加使用项必须坚持的约束。
where
允许指定生命周期和泛型参数的约束。
RFC 介绍 where
包含有关关键字的详细信息。
Examples
where
可用于 traits 的约束:
fn new<T: Default>() -> T {
T::default()
}
fn new_where<T>() -> T
where
T: Default,
{
T::default()
}
assert_eq!(0.0, new());
assert_eq!(0.0, new_where());
assert_eq!(0, new());
assert_eq!(0, new_where());
Runwhere
也可用于生命周期。
这是因为 longer
超过 shorter
而进行编译,因此要遵守约束:
fn select<'short, 'long>(s1: &'short str, s2: &'long str, second: bool) -> &'short str
where
'long: 'short,
{
if second { s2 } else { s1 }
}
let outer = String::from("Long living ref");
let longer = &outer;
{
let inner = String::from("Short living ref");
let shorter = &inner;
assert_eq!(select(shorter, longer, false), shorter);
assert_eq!(select(shorter, longer, true), longer);
}
Run另一方面,由于缺少 where 'b: 'a
子句,因此无法编译:未知 'b
生命周期的生存时间至少与 'a
一样长,这意味着该函数无法确保其始终返回有效的引用:
ⓘ
fn select<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str
{
if second { s2 } else { s1 }
}
Runwhere
也可用于表达无法用 <T: Trait>
语法编写的更复杂的约束:
fn first_or_default<I>(mut i: I) -> I::Item
where
I: Iterator,
I::Item: Default,
{
i.next().unwrap_or_else(I::Item::default)
}
assert_eq!(first_or_default([1, 2, 3].into_iter()), 1);
assert_eq!(first_or_default(Vec::<i32>::new().into_iter()), 0);
Runwhere
在泛型和生命周期参数可用的任何地方都可用,如标准库中的 Cow
类型所示:
pub enum Cow<'a, B>
where
B: ToOwned + ?Sized,
{
Borrowed(&'a B),
Owned(<B as ToOwned>::Owned),
}
Run