diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-12-19 20:38:28 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-12-19 20:38:28 -0700 |
| commit | 2d313fe5011acfa28b8771c5975be37e1c84fd73 (patch) | |
| tree | 9f7f4ae8b617697ebda7102eaecd41efe3061c21 | |
| parent | b865b4b70df27a1e19e7a0cdfedf51d0096da25b (diff) | |
| download | rust-2d313fe5011acfa28b8771c5975be37e1c84fd73.tar.gz rust-2d313fe5011acfa28b8771c5975be37e1c84fd73.zip | |
Update docs to mention trait constraints; also fix failing doc tests
/cc #4217
| -rw-r--r-- | doc/rust.md | 21 | ||||
| -rw-r--r-- | doc/tutorial.md | 33 |
2 files changed, 51 insertions, 3 deletions
diff --git a/doc/rust.md b/doc/rust.md index c73211acef9..8bff1aa37af 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1195,8 +1195,19 @@ Values with a trait type can have [methods called](#method-call-expressions) on for any method in the trait, and can be used to instantiate type parameters that are bounded by the trait. -Trait methods may be static. Currently implementations of static methods behave like -functions declared in the implentation's module. +Trait methods may be static. +Currently, implementations of static methods behave like functions declared in the implementation's module. + +Traits can have _constraints_ for example, in + +~~~~ +trait Shape { fn area() -> float; } +trait Circle : Shape { fn radius() -> float; } +~~~~ + +the syntax `Circle : Shape` means that types that implement `Circle` must also have an implementation for `Shape`. +In an implementation of `Circle` for a given type `T`, methods can refer to `Shape` methods, +since the typechecker checks that any type with an implementation of `Circle` also has an implementation of `Shape`. ### Implementations @@ -1520,8 +1531,11 @@ To indicate that a field is mutable, the `mut` keyword is written before its nam The following are examples of structure expressions: ~~~~ +# struct Point { x: float, y: float } +# mod game { pub struct User { name: &str, age: uint, mut score: uint } } +# use game; Point {x: 10f, y: 20f}; -game::User {name: "Joe", age: 35u, mut score: 100_000}; +let u = game::User {name: "Joe", age: 35u, mut score: 100_000}; ~~~~ A structure expression forms a new value of the named structure type. @@ -1532,6 +1546,7 @@ A new structure will be created, of the same type as the base expression, with t and the values in the base record for all other fields. ~~~~ +# struct Point3d { x: int, y: int, z: int } let base = Point3d {x: 1, y: 2, z: 3}; Point3d {y: 0, z: 10, .. base}; ~~~~ diff --git a/doc/tutorial.md b/doc/tutorial.md index b7eab9b7921..c7b75993f11 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2076,6 +2076,39 @@ the preferred way to use traits polymorphically. This usage of traits is similar to Haskell type classes. +## Trait constraints + +We can write a trait declaration that is _constrained_ to only be implementable on types that +also implement some other trait. + +For example, we can define a `Circle` trait that only types that also have the `Shape` trait can have: + +~~~~ +trait Shape { fn area() -> float; } +trait Circle : Shape { fn radius() -> float; } +~~~~ + +Now, implementations of `Circle` methods can call `Shape` methods: + +~~~~ +# trait Shape { fn area() -> float; } +# trait Circle : Shape { fn radius() -> float; } +# struct Point { x: float, y: float } +# use float::consts::pi; +# use float::sqrt; +# fn square(x: float) -> float { x * x } +struct CircleStruct { center: Point, radius: float } +impl CircleStruct: Circle { + fn radius() -> float { sqrt(self.area() / pi) } +} +impl CircleStruct: Shape { + fn area() -> float { pi * square(self.radius) } +} +~~~~ + +This is a silly way to compute the radius of a circle +(since we could just return the `circle` field), but you get the idea. + ## Trait objects and dynamic method dispatch The above allows us to define functions that polymorphically act on |
