Skip to content

Commit 7c8ff20

Browse files
committed
Reogranise the traits section
1 parent fa836c6 commit 7c8ff20

File tree

1 file changed

+131
-107
lines changed

1 file changed

+131
-107
lines changed

Diff for: src/items.md

+131-107
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ some other [path]. Usually a `use` declaration is used to shorten the path
165165
required to refer to a module item. These declarations may appear in [modules]
166166
and [blocks], usually at the top.
167167

168-
[path]: paths.html [modules]: #modules [blocks]:
169-
../grammar.html#block-expressions
168+
[path]: paths.html
169+
[modules]: #modules
170+
[blocks]: expressions.html#block-expressions
170171

171172
> **Note**: Unlike in many languages, `use` declarations in Rust do *not*
172173
> declare linkage dependency with external crates. Rather, [`extern crate`
@@ -475,7 +476,8 @@ let px: i32 = p.x;
475476
A _tuple struct_ is a nominal [tuple type], also defined with the keyword
476477
`struct`. For example:
477478

478-
[struct type]: types.html#struct-types [tuple type]: types.html#tuple-types
479+
[struct type]: types.html#struct-types
480+
[tuple type]: types.html#tuple-types
479481

480482
```rust
481483
struct Point(i32, i32);
@@ -871,25 +873,23 @@ const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
871873
A _trait_ describes an abstract interface that types can implement. This
872874
interface consists of associated items, which come in three varieties:
873875

874-
- functions
876+
- [functions](#associated-functions-and-methods)
875877
- [types](#associated-types)
876878
- [constants](#associated-constants)
877879

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

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-
891885
Traits are implemented for specific types through separate [implementations].
892886

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

895895
```rust
@@ -903,9 +903,12 @@ trait Shape {
903903

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

908-
[trait object]: types.html#trait-objects [implementations]: #implementations
910+
[trait object]: types.html#trait-objects
911+
[implementations]: #implementations
909912
[syntax]: expressions.html#method-call-expressions
910913

911914
Traits can include default implementations of methods, as in:
@@ -933,6 +936,26 @@ trait Seq<T> {
933936
}
934937
```
935938

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

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

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

9721073
For example:
9731074

9741075
```rust
9751076
# type Surface = i32;
9761077
# trait Shape { fn draw(&self, Surface); }
1078+
struct Figure<S: Shape>(S, S);
9771079
fn draw_twice<T: Shape>(surface: Surface, sh: T) {
9781080
sh.draw(surface);
9791081
sh.draw(surface);
9801082
}
1083+
fn draw_figure<U: Shape>(surface: Surface, Figure(sh1, sh2): Figure<U>) {
1084+
sh1.draw(surface);
1085+
draw_twice(surface, sh2); // Can call this since U: Shape
1086+
}
9811087
```
9821088

1089+
### Trait objects
1090+
9831091
Traits also define a [trait object] with the same name as the trait. Values of
9841092
this type are created by coercing from a pointer of some specific type to a
9851093
pointer of trait type. For example, `&T` could be coerced to `&Shape` if `T:
9861094
Shape` holds (and similarly for `Box<T>`). This coercion can either be implicit
9871095
or [explicit]. Here is an example of an explicit coercion:
9881096

989-
[trait object]: types.html#trait-objects [explicit]:
990-
expressions.html#type-cast-expressions
1097+
[trait object]: types.html#trait-objects
1098+
[explicit]: expressions.html#type-cast-expressions
9911099

9921100
```rust
9931101
trait Shape { }
@@ -1004,24 +1112,13 @@ the trait.
10041112

10051113
[methods called]: expressions.html#method-call-expressions
10061114

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:
1115+
### Supertraits
10121116

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-
```
10231117

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

10261123
```rust
10271124
trait Shape { fn area(&self) -> f64; }
@@ -1082,79 +1179,6 @@ let mycircle = Box::new(mycircle) as Box<Circle>;
10821179
let nonsense = mycircle.radius() * mycircle.area();
10831180
```
10841181

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-
11581182
## Implementations
11591183

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

0 commit comments

Comments
 (0)