Rollup merge of #73762 - poliorcetics:trait-keyword, r=KodrAus
Document the trait keyword Partial fix of #34601. This document the trait keyword. To avoid doing too much and forcing more updates as functionalities evolve, I put two links to the reference, especially for trait objects. This mainly documents the "big" parts, not so much the small details that might trip someone experimenting. @rustbot modify labels: T-doc,C-enhancement
This commit is contained in:
commit
a6266e2d60
@ -1497,11 +1497,188 @@ mod super_keyword {}
|
||||
|
||||
#[doc(keyword = "trait")]
|
||||
//
|
||||
/// A common interface for a class of types.
|
||||
/// A common interface for a group of types.
|
||||
///
|
||||
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
|
||||
/// A `trait` is like an interface that data types can implement. When a type
|
||||
/// implements a trait it can be treated abstractly as that trait using generics
|
||||
/// or trait objects.
|
||||
///
|
||||
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
|
||||
/// Traits can be made up of three varieties of associated items:
|
||||
///
|
||||
/// - functions and methods
|
||||
/// - types
|
||||
/// - constants
|
||||
///
|
||||
/// Traits may also contain additional type parameters. Those type parameters
|
||||
/// or the trait itself can be constrained by other traits.
|
||||
///
|
||||
/// Traits can serve as markers or carry other logical semantics that
|
||||
/// aren't expressed through their items. When a type implements that
|
||||
/// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two
|
||||
/// such marker traits present in the standard library.
|
||||
///
|
||||
/// See the [Reference][Ref-Traits] for a lot more information on traits.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Traits are declared using the `trait` keyword. Types can implement them
|
||||
/// using [`impl`] `Trait` [`for`] `Type`:
|
||||
///
|
||||
/// ```rust
|
||||
/// trait Zero {
|
||||
/// const ZERO: Self;
|
||||
/// fn is_zero(&self) -> bool;
|
||||
/// }
|
||||
///
|
||||
/// impl Zero for i32 {
|
||||
/// const ZERO: Self = 0;
|
||||
///
|
||||
/// fn is_zero(&self) -> bool {
|
||||
/// *self == Self::ZERO
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(i32::ZERO, 0);
|
||||
/// assert!(i32::ZERO.is_zero());
|
||||
/// assert!(!4.is_zero());
|
||||
/// ```
|
||||
///
|
||||
/// With an associated type:
|
||||
///
|
||||
/// ```rust
|
||||
/// trait Builder {
|
||||
/// type Built;
|
||||
///
|
||||
/// fn build(&self) -> Self::Built;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Traits can be generic, with constraints or without:
|
||||
///
|
||||
/// ```rust
|
||||
/// trait MaybeFrom<T> {
|
||||
/// fn maybe_from(value: T) -> Option<Self>
|
||||
/// where
|
||||
/// Self: Sized;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Traits can build upon the requirements of other traits. In the example
|
||||
/// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**:
|
||||
///
|
||||
/// ```rust
|
||||
/// trait ThreeIterator: std::iter::Iterator {
|
||||
/// fn next_three(&mut self) -> Option<[Self::Item; 3]>;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Traits can be used in functions, as parameters:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![allow(dead_code)]
|
||||
/// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug {
|
||||
/// for elem in it {
|
||||
/// println!("{:#?}", elem);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // u8_len_1, u8_len_2 and u8_len_3 are equivalent
|
||||
///
|
||||
/// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize {
|
||||
/// val.into().len()
|
||||
/// }
|
||||
///
|
||||
/// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize {
|
||||
/// val.into().len()
|
||||
/// }
|
||||
///
|
||||
/// fn u8_len_3<T>(val: T) -> usize
|
||||
/// where
|
||||
/// T: Into<Vec<u8>>,
|
||||
/// {
|
||||
/// val.into().len()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Or as return types:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![allow(dead_code)]
|
||||
/// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> {
|
||||
/// (0..v).into_iter()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The use of the [`impl`] keyword in this position allows the function writer
|
||||
/// to hide the concrete type as an implementation detail which can change
|
||||
/// without breaking user's code.
|
||||
///
|
||||
/// # Trait objects
|
||||
///
|
||||
/// A *trait object* is an opaque value of another type that implements a set of
|
||||
/// traits. A trait object implements all specified traits as well as their
|
||||
/// supertraits (if any).
|
||||
///
|
||||
/// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`.
|
||||
/// Only one `BaseTrait` can be used so this will not compile:
|
||||
///
|
||||
/// ```rust,compile_fail,E0225
|
||||
/// trait A {}
|
||||
/// trait B {}
|
||||
///
|
||||
/// let _: Box<dyn A + B>;
|
||||
/// ```
|
||||
///
|
||||
/// Neither will this, which is a syntax error:
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// trait A {}
|
||||
/// trait B {}
|
||||
///
|
||||
/// let _: Box<dyn A + dyn B>;
|
||||
/// ```
|
||||
///
|
||||
/// On the other hand, this is correct:
|
||||
///
|
||||
/// ```rust
|
||||
/// trait A {}
|
||||
///
|
||||
/// let _: Box<dyn A + Send + Sync>;
|
||||
/// ```
|
||||
///
|
||||
/// The [Reference][Ref-Trait-Objects] has more information about trait objects,
|
||||
/// their limitations and the differences between editions.
|
||||
///
|
||||
/// # Unsafe traits
|
||||
///
|
||||
/// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in
|
||||
/// front of the trait's declaration is used to mark this:
|
||||
///
|
||||
/// ```rust
|
||||
/// unsafe trait UnsafeTrait {}
|
||||
///
|
||||
/// unsafe impl UnsafeTrait for i32 {}
|
||||
/// ```
|
||||
///
|
||||
/// # Differences between the 2015 and 2018 editions
|
||||
///
|
||||
/// In the 2015 edition parameters pattern where not needed for traits:
|
||||
///
|
||||
/// ```rust,edition2015
|
||||
/// trait Tr {
|
||||
/// fn f(i32);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This behavior is no longer valid in edition 2018.
|
||||
///
|
||||
/// [`for`]: keyword.for.html
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [`unsafe`]: keyword.unsafe.html
|
||||
/// [`Send`]: marker/trait.Send.html
|
||||
/// [`Sync`]: marker/trait.Sync.html
|
||||
/// [Ref-Traits]: ../reference/items/traits.html
|
||||
/// [Ref-Trait-Objects]: ../reference/types/trait-object.html
|
||||
mod trait_keyword {}
|
||||
|
||||
#[doc(keyword = "true")]
|
||||
|
Loading…
x
Reference in New Issue
Block a user