`<T: Trait>` 和 `where T: Trait` 有什么区别? [英] What's the difference between `<T: Trait>` and `where T: Trait`?
问题描述
在文档中,用于Send
trait,我看到了
impl发送链接列表在哪里T:发送,
和
impl发送链接列表
这两种语法有什么区别,如果我为自己的 trait 编写 impl
声明,它会如何影响我的代码?
在 where
子句中定义的特征边界是内联声明的特征边界的超集.内联样式存在于 where
子句之前;where
子句是引入在 RFC 135 中:
添加 where
子句,它提供了一种更具表现力的方式指定特征参数边界.[...] 现有的边界符号将保留为 where
子句的语法糖.
<块引用>
这是当前边界语法的限制列表用 where 语法克服:
它不能表达除类型参数以外的任何东西的界限.因此,如果您在
T
中有一个泛型函数,您可以编写T:MyTrait
声明T
必须实现MyTrait
,但你不能写Option
或;: MyTrait (int, T) : MyTrait
.这些表格比较少通常需要但仍然很重要.它不适用于关联类型.这是因为没有空间指定关联类型的值.其他语言为此目的使用 where 子句(或类似的东西).
简直难以阅读.经验表明,随着边界数量的增加,当前的语法变得难以阅读并且格式.
从那时起,您还可以在 where
子句中使用 排名较高的特征边界(for <'a> ...
):
fn foo()在哪里//排名较高的特征边界对于<'a>T:别的东西<'a>,//不直接绑定在泛型类型上i32:来自<U>,T:迭代器,//绑定在关联类型上T::项目:克隆,//真的很长U:ReallyLong + AnotherReallyLong + WowReallyLong,{}
如果内联特征边界可以满足您的需求,那么对您的代码没有影响.如果您需要仅 where
启用的额外功能,那么您需要使用 where
.
另见:
我的个人风格是总是使用where
表单.在添加新边界时,拥有一个更容易git diff
的单一形状对我来说值得多写一行代码.
In the docs for the Send
trait, I see both
impl<T> Send for LinkedList<T>
where
T: Send,
and
impl<T: Send> Send for LinkedList<T>
What is the difference between these two syntaxes, and how would it impact my code if I was writing impl
declarations for my own trait?
Trait bounds defined inside a where
clause are a superset of the trait bounds declared inline. The inline style existed before the where
clause; the where
clause was 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.
Since then you can also use higher-ranked trait bounds (for <'a> ...
) in a where
clause:
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,
{}
If your needs can be met by the inline trait bounds, then there is no impact on your code. If you need the extra powers that only where
enables, then you need to use where
.
See also:
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.
这篇关于`<T: Trait>` 和 `where T: Trait` 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!