From d43908a3a7b2889b847306070593f58b93ca1a6b Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 13 May 2013 18:32:35 +1000 Subject: [PATCH] doc: document the #[deriving] attribute. Closes #4916. --- doc/rust.md | 43 +++++++++++++++++++++++++++++++++++++++++++ doc/tutorial.md | 21 +++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/doc/rust.md b/doc/rust.md index 60848441e4e77..8dbc503d32e2a 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1425,6 +1425,8 @@ names are effectively reserved. Some significant attributes include: * The `test` attribute, for marking functions as unit tests. * The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint checks. Lint checks supported by the compiler can be found via `rustc -W help`. +* The `deriving` attribute, for automatically generating + implementations of certain traits. Other attributes may be added or removed during development of the language. @@ -1526,6 +1528,47 @@ A complete list of the built-in language items follows: > **Note:** This list is likely to become out of date. We should auto-generate it > from `librustc/middle/lang_items.rs`. +### Deriving + +The `deriving` attribute allows certain traits to be automatically +implemented for data structures. For example, the following will +create an `impl` for the `Eq` and `Clone` traits for `Foo`, the type +parameter `T` will be given the `Eq` or `Clone` constraints for the +appropriate `impl`: + +~~~ +#[deriving(Eq, Clone)] +struct Foo { + a: int, + b: T +} +~~~ + +The generated `impl` for `Eq` is equivalent to + +~~~ +# struct Foo { a: int, b: T } +impl Eq for Foo { + fn eq(&self, other: &Foo) -> bool { + self.a == other.a && self.b == other.b + } + + fn ne(&self, other: &Foo) -> bool { + self.a != other.a || self.b != other.b + } +} +~~~ + +Supported traits for `deriving` are: + +* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`. +* Serialization: `Encodable`, `Decodable`. These require `std`. +* `Clone`, to perform deep copies. +* `IterBytes`, to iterate over the bytes in a data type. +* `Rand`, to create a random instance of a data type. +* `ToStr`, to convert to a string. For a type with this instance, + `obj.to_str()` has the same output as `fmt!("%?", obj)`. + # Statements and expressions Rust is _primarily_ an expression language. This means that most forms of diff --git a/doc/tutorial.md b/doc/tutorial.md index 3582acbe0f6b8..4a680d0130325 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2290,6 +2290,27 @@ let nonsense = mycircle.radius() * mycircle.area(); > ***Note:*** Trait inheritance does not actually work with objects yet +## Deriving implementations for traits + +A small number of traits in `core` and `std` can have implementations +that can be automatically derived. These instances are specified by +placing the `deriving` attribute on a data type declaration. For +example, the following will mean that `Circle` has an implementation +for `Eq` and can be used with the equality operators, and that a value +of type `ABC` can be randomly generated and converted to a string: + +~~~ +#[deriving(Eq)] +struct Circle { radius: float } + +#[deriving(Rand, ToStr)] +enum ABC { A, B, C } +~~~ + +The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, +`TotalOrd`, `Encodable` `Decodable`, `Clone`, `IterBytes`, `Rand` and +`ToStr`. + # Modules and crates The Rust namespace is arranged in a hierarchy of modules. Each source