`<T: Trait>` 和 `where T: Trait` 有什么区别? [英] What's the difference between `<T: Trait>` and `where T: Trait`?

查看:46
本文介绍了`<T: Trait>` 和 `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 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.

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.

这篇关于`&lt;T: Trait&gt;` 和 `where T: Trait` 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆