Keyword where

source ·
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());
Run

where 也可用于生命周期。

这是因为 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 }
}
Run

where 也可用于表达无法用 <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);
Run

where 在泛型和生命周期参数可用的任何地方都可用,如标准库中的 Cow 类型所示:

pub enum Cow<'a, B>
where
    B: ToOwned + ?Sized,
{
    Borrowed(&'a B),
    Owned(<B as ToOwned>::Owned),
}
Run