@@ -1497,11 +1497,188 @@ mod super_keyword {}
1497
1497
1498
1498
#[ doc( keyword = "trait" ) ]
1499
1499
//
1500
- /// A common interface for a class of types.
1500
+ /// A common interface for a group of types.
1501
1501
///
1502
- /// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1502
+ /// A `trait` is like an interface that data types can implement. When a type
1503
+ /// implements a trait it can be treated abstractly as that trait using generics
1504
+ /// or trait objects.
1503
1505
///
1504
- /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1506
+ /// Traits can be made up of three varieties of associated items:
1507
+ ///
1508
+ /// - functions and methods
1509
+ /// - types
1510
+ /// - constants
1511
+ ///
1512
+ /// Traits may also contain additional type parameters. Those type parameters
1513
+ /// or the trait itself can be constrained by other traits.
1514
+ ///
1515
+ /// Traits can serve as markers or carry other logical semantics that
1516
+ /// aren't expressed through their items. When a type implements that
1517
+ /// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two
1518
+ /// such marker traits present in the standard library.
1519
+ ///
1520
+ /// See the [Reference][Ref-Traits] for a lot more information on traits.
1521
+ ///
1522
+ /// # Examples
1523
+ ///
1524
+ /// Traits are declared using the `trait` keyword. Types can implement them
1525
+ /// using [`impl`] `Trait` [`for`] `Type`:
1526
+ ///
1527
+ /// ```rust
1528
+ /// trait Zero {
1529
+ /// const ZERO: Self;
1530
+ /// fn is_zero(&self) -> bool;
1531
+ /// }
1532
+ ///
1533
+ /// impl Zero for i32 {
1534
+ /// const ZERO: Self = 0;
1535
+ ///
1536
+ /// fn is_zero(&self) -> bool {
1537
+ /// *self == Self::ZERO
1538
+ /// }
1539
+ /// }
1540
+ ///
1541
+ /// assert_eq!(i32::ZERO, 0);
1542
+ /// assert!(i32::ZERO.is_zero());
1543
+ /// assert!(!4.is_zero());
1544
+ /// ```
1545
+ ///
1546
+ /// With an associated type:
1547
+ ///
1548
+ /// ```rust
1549
+ /// trait Builder {
1550
+ /// type Built;
1551
+ ///
1552
+ /// fn build(&self) -> Self::Built;
1553
+ /// }
1554
+ /// ```
1555
+ ///
1556
+ /// Traits can be generic, with constraints or without:
1557
+ ///
1558
+ /// ```rust
1559
+ /// trait MaybeFrom<T> {
1560
+ /// fn maybe_from(value: T) -> Option<Self>
1561
+ /// where
1562
+ /// Self: Sized;
1563
+ /// }
1564
+ /// ```
1565
+ ///
1566
+ /// Traits can build upon the requirements of other traits. In the example
1567
+ /// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**:
1568
+ ///
1569
+ /// ```rust
1570
+ /// trait ThreeIterator: std::iter::Iterator {
1571
+ /// fn next_three(&mut self) -> Option<[Self::Item; 3]>;
1572
+ /// }
1573
+ /// ```
1574
+ ///
1575
+ /// Traits can be used in functions, as parameters:
1576
+ ///
1577
+ /// ```rust
1578
+ /// # #![allow(dead_code)]
1579
+ /// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug {
1580
+ /// for elem in it {
1581
+ /// println!("{:#?}", elem);
1582
+ /// }
1583
+ /// }
1584
+ ///
1585
+ /// // u8_len_1, u8_len_2 and u8_len_3 are equivalent
1586
+ ///
1587
+ /// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize {
1588
+ /// val.into().len()
1589
+ /// }
1590
+ ///
1591
+ /// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize {
1592
+ /// val.into().len()
1593
+ /// }
1594
+ ///
1595
+ /// fn u8_len_3<T>(val: T) -> usize
1596
+ /// where
1597
+ /// T: Into<Vec<u8>>,
1598
+ /// {
1599
+ /// val.into().len()
1600
+ /// }
1601
+ /// ```
1602
+ ///
1603
+ /// Or as return types:
1604
+ ///
1605
+ /// ```rust
1606
+ /// # #![allow(dead_code)]
1607
+ /// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> {
1608
+ /// (0..v).into_iter()
1609
+ /// }
1610
+ /// ```
1611
+ ///
1612
+ /// The use of the [`impl`] keyword in this position allows the function writer
1613
+ /// to hide the concrete type as an implementation detail which can change
1614
+ /// without breaking user's code.
1615
+ ///
1616
+ /// # Trait objects
1617
+ ///
1618
+ /// A *trait object* is an opaque value of another type that implements a set of
1619
+ /// traits. A trait object implements all specified traits as well as their
1620
+ /// supertraits (if any).
1621
+ ///
1622
+ /// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`.
1623
+ /// Only one `BaseTrait` can be used so this will not compile:
1624
+ ///
1625
+ /// ```rust,compile_fail,E0225
1626
+ /// trait A {}
1627
+ /// trait B {}
1628
+ ///
1629
+ /// let _: Box<dyn A + B>;
1630
+ /// ```
1631
+ ///
1632
+ /// Neither will this, which is a syntax error:
1633
+ ///
1634
+ /// ```rust,compile_fail
1635
+ /// trait A {}
1636
+ /// trait B {}
1637
+ ///
1638
+ /// let _: Box<dyn A + dyn B>;
1639
+ /// ```
1640
+ ///
1641
+ /// On the other hand, this is correct:
1642
+ ///
1643
+ /// ```rust
1644
+ /// trait A {}
1645
+ ///
1646
+ /// let _: Box<dyn A + Send + Sync>;
1647
+ /// ```
1648
+ ///
1649
+ /// The [Reference][Ref-Trait-Objects] has more information about trait objects,
1650
+ /// their limitations and the differences between editions.
1651
+ ///
1652
+ /// # Unsafe traits
1653
+ ///
1654
+ /// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in
1655
+ /// front of the trait's declaration is used to mark this:
1656
+ ///
1657
+ /// ```rust
1658
+ /// unsafe trait UnsafeTrait {}
1659
+ ///
1660
+ /// unsafe impl UnsafeTrait for i32 {}
1661
+ /// ```
1662
+ ///
1663
+ /// # Differences between the 2015 and 2018 editions
1664
+ ///
1665
+ /// In the 2015 edition parameters pattern where not needed for traits:
1666
+ ///
1667
+ /// ```rust,edition2015
1668
+ /// trait Tr {
1669
+ /// fn f(i32);
1670
+ /// }
1671
+ /// ```
1672
+ ///
1673
+ /// This behavior is no longer valid in edition 2018.
1674
+ ///
1675
+ /// [`for`]: keyword.for.html
1676
+ /// [`impl`]: keyword.impl.html
1677
+ /// [`unsafe`]: keyword.unsafe.html
1678
+ /// [`Send`]: marker/trait.Send.html
1679
+ /// [`Sync`]: marker/trait.Sync.html
1680
+ /// [Ref-Traits]: ../reference/items/traits.html
1681
+ /// [Ref-Trait-Objects]: ../reference/types/trait-object.html
1505
1682
mod trait_keyword { }
1506
1683
1507
1684
#[ doc( keyword = "true" ) ]
0 commit comments