Skip to content

Commit 88b90fe

Browse files
committed
Reogranise the traits section
1 parent fa836c6 commit 88b90fe

File tree

1 file changed

+126
-104
lines changed

1 file changed

+126
-104
lines changed

src/items.md

Lines changed: 126 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -871,25 +871,23 @@ const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
871871
A _trait_ describes an abstract interface that types can implement. This
872872
interface consists of associated items, which come in three varieties:
873873

874-
- functions
874+
- [functions](#associated-functions-and-methods)
875875
- [types](#associated-types)
876876
- [constants](#associated-constants)
877877

878-
Associated functions whose first parameter is named `self` are called methods
879-
and may be invoked using `.` notation (e.g., `x.foo()`).
880-
881878
All traits define an implicit type parameter `Self` that refers to "the type
882879
that is implementing this interface". Traits may also contain additional type
883880
parameters. These type parameters (including `Self`) may be constrained by
884881
other traits and so forth as usual.
885882

886-
Trait bounds on `Self` are considered "supertraits". These are required to be
887-
acyclic. Supertraits are somewhat different from other constraints in that
888-
they affect what methods are available in the vtable when the trait is used as
889-
a [trait object].
890-
891883
Traits are implemented for specific types through separate [implementations].
892884

885+
### Associated functions and methods
886+
887+
Associated functions whose first parameter is named `self` are called methods
888+
and may be invoked using `.` notation (e.g., `x.foo()`) as well as the usual
889+
function call notation (`foo(x)`).
890+
893891
Consider the following trait:
894892

895893
```rust
@@ -903,9 +901,12 @@ trait Shape {
903901

904902
This defines a trait with two methods. All values that have [implementations]
905903
of this trait in scope can have their `draw` and `bounding_box` methods called,
906-
using `value.bounding_box()` [syntax].
904+
using `value.bounding_box()` [syntax]. Note that `&self` is short for `self:
905+
&Self`, and similarly, `self` is short for `self: Self` and `&mut self` is
906+
short for `self: &mut Self`.
907907

908-
[trait object]: types.html#trait-objects [implementations]: #implementations
908+
[trait object]: types.html#trait-objects
909+
[implementations]: #implementations
909910
[syntax]: expressions.html#method-call-expressions
910911

911912
Traits can include default implementations of methods, as in:
@@ -933,6 +934,26 @@ trait Seq<T> {
933934
}
934935
```
935936

937+
Associated functions may lack a `self` argument, sometimes called 'static
938+
methods'. This means that they can only be called with function call syntax
939+
(`f(x)`) and not method call syntax (`obj.f()`). The way to refer to the name
940+
of a static method is to qualify it with the trait name or type name, treating
941+
the trait name like a module. For example:
942+
943+
```rust
944+
trait Num {
945+
fn from_i32(n: i32) -> Self;
946+
}
947+
impl Num for f64 {
948+
fn from_i32(n: i32) -> f64 { n as f64 }
949+
}
950+
let x: f64 = Num::from_i32(42);
951+
let x: f64 = f64::from_i32(42);
952+
```
953+
954+
955+
### Associated Types
956+
936957
It is also possible to define associated types for a trait. Consider the
937958
following example of a `Container` trait. Notice how the type is available for
938959
use in the method signatures:
@@ -962,32 +983,117 @@ impl<T> Container for Vec<T> {
962983
}
963984
```
964985

986+
### Associated Constants
987+
988+
A trait can define constants like this:
989+
990+
```rust
991+
trait Foo {
992+
const ID: i32;
993+
}
994+
995+
impl Foo for i32 {
996+
const ID: i32 = 1;
997+
}
998+
999+
fn main() {
1000+
assert_eq!(1, i32::ID);
1001+
}
1002+
```
1003+
1004+
Any implementor of `Foo` will have to define `ID`. Without the definition:
1005+
1006+
```rust,compile_fail,E0046
1007+
trait Foo {
1008+
const ID: i32;
1009+
}
1010+
1011+
impl Foo for i32 {
1012+
}
1013+
```
1014+
1015+
gives
1016+
1017+
```text
1018+
error: not all trait items implemented, missing: `ID` [E0046]
1019+
impl Foo for i32 {
1020+
}
1021+
```
1022+
1023+
A default value can be implemented as well:
1024+
1025+
```rust
1026+
trait Foo {
1027+
const ID: i32 = 1;
1028+
}
1029+
1030+
impl Foo for i32 {
1031+
}
1032+
1033+
impl Foo for i64 {
1034+
const ID: i32 = 5;
1035+
}
1036+
1037+
fn main() {
1038+
assert_eq!(1, i32::ID);
1039+
assert_eq!(5, i64::ID);
1040+
}
1041+
```
1042+
1043+
As you can see, when implementing `Foo`, you can leave it unimplemented, as
1044+
with `i32`. It will then use the default value. But, as in `i64`, we can also
1045+
add our own definition.
1046+
1047+
Associated constants don’t have to be associated with a trait. An `impl` block
1048+
for a `struct` or an `enum` works fine too:
1049+
1050+
```rust
1051+
struct Foo;
1052+
1053+
impl Foo {
1054+
const FOO: u32 = 3;
1055+
}
1056+
```
1057+
1058+
### Trait bounds
1059+
9651060
Generic functions may use traits as _bounds_ on their type parameters. This
966-
will have two effects:
1061+
will have three effects:
9671062

9681063
- Only types that have the trait may instantiate the parameter.
9691064
- Within the generic function, the methods of the trait can be called on values
970-
that have the parameter's type.
1065+
that have the parameter's type. Associated types can be used in the
1066+
function's signature, and associated constants can be used in expressions
1067+
within the function body.
1068+
- Generic functions and types with the same or weaker bounds can use the
1069+
generic type in the function body or signature.
9711070

9721071
For example:
9731072

9741073
```rust
9751074
# type Surface = i32;
9761075
# trait Shape { fn draw(&self, Surface); }
1076+
struct Figure<S: Shape>(S, S);
9771077
fn draw_twice<T: Shape>(surface: Surface, sh: T) {
9781078
sh.draw(surface);
9791079
sh.draw(surface);
9801080
}
1081+
fn draw_figure<U: Shape>(surface: Surface, Figure(sh1, sh2): Figure<U>) {
1082+
sh1.draw(surface);
1083+
draw_twice(surface, sh2); // Can call this since U: Shape
1084+
}
9811085
```
9821086

1087+
### Trait objects
1088+
9831089
Traits also define a [trait object] with the same name as the trait. Values of
9841090
this type are created by coercing from a pointer of some specific type to a
9851091
pointer of trait type. For example, `&T` could be coerced to `&Shape` if `T:
9861092
Shape` holds (and similarly for `Box<T>`). This coercion can either be implicit
9871093
or [explicit]. Here is an example of an explicit coercion:
9881094

989-
[trait object]: types.html#trait-objects [explicit]:
990-
expressions.html#type-cast-expressions
1095+
[trait object]: types.html#trait-objects
1096+
[explicit]: expressions.html#type-cast-expressions
9911097

9921098
```rust
9931099
trait Shape { }
@@ -1004,24 +1110,13 @@ the trait.
10041110

10051111
[methods called]: expressions.html#method-call-expressions
10061112

1007-
Trait methods may be static, which means that they lack a `self` argument. This
1008-
means that they can only be called with function call syntax (`f(x)`) and not
1009-
method call syntax (`obj.f()`). The way to refer to the name of a static method
1010-
is to qualify it with the trait name or type name, treating the trait name like
1011-
a module. For example:
1113+
### Supertraits
10121114

1013-
```rust
1014-
trait Num {
1015-
fn from_i32(n: i32) -> Self;
1016-
}
1017-
impl Num for f64 {
1018-
fn from_i32(n: i32) -> f64 { n as f64 }
1019-
}
1020-
let x: f64 = Num::from_i32(42);
1021-
let x: f64 = f64::from_i32(42);
1022-
```
10231115

1024-
Traits may inherit from other traits. Consider the following example:
1116+
Trait bounds on `Self` are considered "supertraits". These are required to be
1117+
acyclic. Supertraits are somewhat different from other constraints in that
1118+
they affect what methods are available in the vtable when the trait is used as
1119+
a [trait object]. Consider the following example:
10251120

10261121
```rust
10271122
trait Shape { fn area(&self) -> f64; }
@@ -1082,79 +1177,6 @@ let mycircle = Box::new(mycircle) as Box<Circle>;
10821177
let nonsense = mycircle.radius() * mycircle.area();
10831178
```
10841179

1085-
### Associated Constants
1086-
1087-
1088-
A trait can define constants like this:
1089-
1090-
```rust
1091-
trait Foo {
1092-
const ID: i32;
1093-
}
1094-
1095-
impl Foo for i32 {
1096-
const ID: i32 = 1;
1097-
}
1098-
1099-
fn main() {
1100-
assert_eq!(1, i32::ID);
1101-
}
1102-
```
1103-
1104-
Any implementor of `Foo` will have to define `ID`. Without the definition:
1105-
1106-
```rust,compile_fail,E0046
1107-
trait Foo {
1108-
const ID: i32;
1109-
}
1110-
1111-
impl Foo for i32 {
1112-
}
1113-
```
1114-
1115-
gives
1116-
1117-
```text
1118-
error: not all trait items implemented, missing: `ID` [E0046]
1119-
impl Foo for i32 {
1120-
}
1121-
```
1122-
1123-
A default value can be implemented as well:
1124-
1125-
```rust
1126-
trait Foo {
1127-
const ID: i32 = 1;
1128-
}
1129-
1130-
impl Foo for i32 {
1131-
}
1132-
1133-
impl Foo for i64 {
1134-
const ID: i32 = 5;
1135-
}
1136-
1137-
fn main() {
1138-
assert_eq!(1, i32::ID);
1139-
assert_eq!(5, i64::ID);
1140-
}
1141-
```
1142-
1143-
As you can see, when implementing `Foo`, you can leave it unimplemented, as
1144-
with `i32`. It will then use the default value. But, as in `i64`, we can also
1145-
add our own definition.
1146-
1147-
Associated constants don’t have to be associated with a trait. An `impl` block
1148-
for a `struct` or an `enum` works fine too:
1149-
1150-
```rust
1151-
struct Foo;
1152-
1153-
impl Foo {
1154-
const FOO: u32 = 3;
1155-
}
1156-
```
1157-
11581180
## Implementations
11591181

11601182
An _implementation_ is an item that can implement a [trait](#traits) for a

0 commit comments

Comments
 (0)