This is a conventions RFC establishing a definition定義
and naming convention for extension traits: FooExt
.
This RFC is part of the ongoing API conventions and stabilization effort.
Extension traits are a programmingプログラミング
pattern that makes it possible to add methods to an existing type outside of the crate defining that type. While they should be used sparingly, the new object safety rules have increased増加する、昇順の
the need for this kind of trait, and hence the need for a clear convention.
Rust currently allows許可する、可能にする
inherent methods to be defined定義する
on a type only in the crate where that type is defined.定義する
But it is often the case that clients of a type would like to incorporate additional追加の
methods to it. Extension traits are a pattern for doing so:
#![allow(unused)]
fn main() {
extern crate foo;
use foo::Foo;
trait FooExt {
fn bar(&self);
}
impl FooExt for Foo {
fn bar(&self) { .. }
}
}
By defining a new trait, a client of foo
can add new methods to Foo
.
Of course, addingたす
methods via a new trait happens all the time. What makes it an extension trait is that the trait is not designed設計(する)
for generic use, but only as way of addingたす
methods to a specific特定の
type or family of types.
This is of course a somewhat subjective distinction. Whenever designing設計(する)
an extension trait, one should consider考える、みなす
whether the trait could be used in some more generic way. If so, the trait should be named and exported as if it were just a "normal" trait. But traits offering groups of methods that really only make sense in the context文脈、背景
of some particular type(s) are true extension traits.
The new object safety rules mean that a trait can only be used for trait objects if all of its methods are usable; put differently, it ensures that for "object safe traits" there is always a canonical way to implement実装する
Trait
for Box<Trait>
. To deal with this new rule, it is sometimes necessary to break traits apart into an object safe trait and extension traits:
#![allow(unused)]
fn main() {
trait Iterator<A> {
fn next(&mut self) -> Option<A>;
}
trait IteratorExt<A>: Iterator<A> {
fn chain<U: Iterator<A>>(self, other: U) -> Chain<Self, U> { ... }
fn zip<B, U: Iterator<B>>(self, other: U) -> Zip<Self, U> { ... }
fn map<B>(self, f: |A| -> B) -> Map<'r, A, B, Self> { ... }
...
}
impl<A, I> IteratorExt<A> for I where I: Iterator<A> {
...
}
}
Note that, although this split-up definition定義
is somewhat more complex,複素数、複文の
it is also more flexible: because Box<Iterator<A>>
will implement実装する
Iterator<A>
, you can now use all of the adapter methods provided与える
in IteratorExt
on trait objects, even though they are not object safe.
The proposed convention is, first of all, to (1) prefer addingたす
default methods to existing traits or (2) prefer generically useful traits to extension traits whenever feasible.
For true extension traits, there should be a clear type or trait that they are extending.拡張する
The extension trait should be called呼び出し
FooExt
where Foo
is that type or trait.
In some cases, the extension trait only applies適用する
conditionally. For example, AdditiveIterator
is an extension trait currently in std
that applies適用する
to iterators over numeric数の、数値の
types. These extension traits should follow下記の、次に続く、追従する
a similar似ている、同様の
convention, putting together the type/trait name and the qualifications, together with the Ext
suffix: IteratorAddExt
.
A previous前の
convention used a Prelude
suffix for extension traits that were also part of the std
prelude; this new convention deprecates that one.
In the future, the need for many of these extension traits may disappear as other languages言語
features are added.たす
For example, method-level where
clauses句、節
will eliminate the need for AdditiveIterator
. And allowing許可する、可能にする
inherent impl
s like impl<T: Trait> T { .. }
for the crate defining Trait
would eliminate even more.
However, there will always be some use of extension traits, and we need to stabilize the 1.0 libraries prior to these language言語
features landing. So this is the proposed convention for now, and in the future it may be possible to deprecate some of the resulting結果、戻り値
traits.
It seems clear that we need some convention here. Other possible suffixes would be Util
or Methods
, but Ext
is both shorter and connects to the name of the pattern.
In general,一般
extension traits tend to require additional追加の
imports -- especially painful when dealing with object safety. However, this is more to do with the language言語
as it stands today than with the conventions in this RFC.
Libraries are already starting to export their own prelude
module containing含む
extension traits among other things, which by convention is glob imported.
In the long run, we should add a general一般
"prelude" facility施設、設備
for external libraries that makes it possible to globally import a small setセットする、集合
of names from the crate. Some early investigations of such a feature are already under way, but are outside the scope of this RFC.