`<T: Trait>` 和 `where T: Trait` 有什么区别?
What's the difference between `<T: Trait>` and `where T: Trait`?
在 the docs 中,对于 Send
特征,我看到了两者
impl<T> Send for LinkedList<T>
where
T: Send,
和
impl<T: Send> Send for LinkedList<T>
这两种语法有什么区别,如果我为自己的特征编写 impl
声明,它会对我的代码产生什么影响?
where
子句中定义的特征边界是内联声明的特征边界的超集。内联样式存在于 where
子句之前; where
子句是 introduced in RFC 135:
Add where
clauses, which provide a more expressive means of
specifying trait parameter bounds. [...] The existing bounds notation
would remain as syntactic sugar for where
clauses.
Here is a list of limitations with the current bounds syntax that are
overcome with the where syntax:
It cannot express bounds on anything other than type parameters. Therefore, if you have a function generic in T
, you can write
T:MyTrait
to declare that T
must implement MyTrait
, but you can't
write Option<T> : MyTrait
or (int, T) : MyTrait
. These forms are less
commonly required but still important.
It does not work well with associated types. This is because there is no space to specify the value of an associated type. Other
languages use where clauses (or something analogous) for this purpose.
It's just plain hard to read. Experience has shown that as the number of bounds grows, the current syntax becomes hard to read and
format.
从那时起,您还可以在 where
子句中使用 higher-ranked trait bounds (for <'a> ...
):
fn foo<T, U>()
where
// higher-ranked trait bounds
for<'a> T: SomethingElse<'a>,
// Bound not directly on the generic type
i32: From<U>,
T: Iterator,
// Bound on an associated type
T::Item: Clone,
// Just really long
U: ReallyLong + AnotherReallyLong + WowReallyLong,
{}
如果inline trait bounds可以满足你的需求,那么对你的代码没有影响。如果您需要仅 where
启用的额外功能,则需要使用 where
.
另请参阅:
我的个人风格是总是使用where
表格。在添加新边界时拥有一个更容易 git diff
的单一形状对我来说值得额外的代码行。
where
clause documentation 现在包括示例:
When specifying generic types and bounds separately is clearer:
impl <A: TraitB + TraitC, D: TraitE + TraitF> MyTrait<A, D> for YourType {}
// Expressing bounds with a `where` clause
impl <A, D> MyTrait<A, D> for YourType where
A: TraitB + TraitC,
D: TraitE + TraitF {}
shepmaster 提及:
My personal style is to always use the where form.
Having a single shape that is also easier to git diff
when adding new bounds is worth the extra line of code for me.
我同意,考虑到 Git 2.23(2019 年第 3 季度)将在其函数名和文字中添加 rust
边界。
参见 commit 33be7b3 (30 May 2019) by Johannes Sixt (j6t
)。
参见 commit d74e786 (16 May 2019) by Marc-André Lureau (``)。
(由 Junio C Hamano -- gitster
-- in commit a41dad4 合并,2019 年 6 月 21 日)
userdiff: add built-in pattern for rust
This adds xfuncname
and word_regex
patterns for Rust, a quite popular programming language.
It also includes test cases for the xfuncname
regex (t4018) and updated documentation.
在 the docs 中,对于 Send
特征,我看到了两者
impl<T> Send for LinkedList<T>
where
T: Send,
和
impl<T: Send> Send for LinkedList<T>
这两种语法有什么区别,如果我为自己的特征编写 impl
声明,它会对我的代码产生什么影响?
where
子句中定义的特征边界是内联声明的特征边界的超集。内联样式存在于 where
子句之前; where
子句是 introduced in RFC 135:
Add
where
clauses, which provide a more expressive means of specifying trait parameter bounds. [...] The existing bounds notation would remain as syntactic sugar forwhere
clauses.
Here is a list of limitations with the current bounds syntax that are overcome with the where syntax:
It cannot express bounds on anything other than type parameters. Therefore, if you have a function generic in
T
, you can writeT:MyTrait
to declare thatT
must implementMyTrait
, but you can't writeOption<T> : MyTrait
or(int, T) : MyTrait
. These forms are less commonly required but still important.It does not work well with associated types. This is because there is no space to specify the value of an associated type. Other languages use where clauses (or something analogous) for this purpose.
It's just plain hard to read. Experience has shown that as the number of bounds grows, the current syntax becomes hard to read and format.
从那时起,您还可以在 where
子句中使用 higher-ranked trait bounds (for <'a> ...
):
fn foo<T, U>()
where
// higher-ranked trait bounds
for<'a> T: SomethingElse<'a>,
// Bound not directly on the generic type
i32: From<U>,
T: Iterator,
// Bound on an associated type
T::Item: Clone,
// Just really long
U: ReallyLong + AnotherReallyLong + WowReallyLong,
{}
如果inline trait bounds可以满足你的需求,那么对你的代码没有影响。如果您需要仅 where
启用的额外功能,则需要使用 where
.
另请参阅:
我的个人风格是总是使用where
表格。在添加新边界时拥有一个更容易 git diff
的单一形状对我来说值得额外的代码行。
where
clause documentation 现在包括示例:
When specifying generic types and bounds separately is clearer:
impl <A: TraitB + TraitC, D: TraitE + TraitF> MyTrait<A, D> for YourType {}
// Expressing bounds with a `where` clause
impl <A, D> MyTrait<A, D> for YourType where
A: TraitB + TraitC,
D: TraitE + TraitF {}
shepmaster 提及:
My personal style is to always use the where form.
Having a single shape that is also easier togit diff
when adding new bounds is worth the extra line of code for me.
我同意,考虑到 Git 2.23(2019 年第 3 季度)将在其函数名和文字中添加 rust 边界。
参见 commit 33be7b3 (30 May 2019) by Johannes Sixt (j6t
)。
参见 commit d74e786 (16 May 2019) by Marc-André Lureau (``)。
(由 Junio C Hamano -- gitster
-- in commit a41dad4 合并,2019 年 6 月 21 日)
userdiff: add built-in pattern for rust
This adds
xfuncname
andword_regex
patterns for Rust, a quite popular programming language.
It also includes test cases for thexfuncname
regex (t4018) and updated documentation.