::from_i32(42);
let _: f64 = f64::from_i32(42);
```
### Methods
Associated functions whose first parameter is named `self` are called *methods*
and may be invoked using the [method call operator], for example, `x.foo()`, as
well as the usual function call notation.
If the type of the `self` parameter is specified, it is limited to types resolving
to one generated by the following grammar (where `'lt` denotes some arbitrary
lifetime):
```text
P = &'lt S | &'lt mut S | Box | Rc | Arc | Pin
S = Self | P
```
The `Self` terminal in this grammar denotes a type resolving to the implementing type.
This can also include the contextual type alias `Self`, other type aliases,
or associated type projections resolving to the implementing type.
```rust
# use std::rc::Rc;
# use std::sync::Arc;
# use std::pin::Pin;
// Examples of methods implemented on struct `Example`.
struct Example;
type Alias = Example;
trait Trait { type Output; }
impl Trait for Example { type Output = Example; }
impl Example {
fn by_value(self: Self) {}
fn by_ref(self: &Self) {}
fn by_ref_mut(self: &mut Self) {}
fn by_box(self: Box) {}
fn by_rc(self: Rc) {}
fn by_arc(self: Arc) {}
fn by_pin(self: Pin<&Self>) {}
fn explicit_type(self: Arc) {}
fn with_lifetime<'a>(self: &'a Self) {}
fn nested<'a>(self: &mut &'a Arc>>) {}
fn via_projection(self: ::Output) {}
}
```
Shorthand syntax can be used without specifying a type, which have the
following equivalents:
Shorthand | Equivalent
----------------------|-----------
`self` | `self: Self`
`&'lifetime self` | `self: &'lifetime Self`
`&'lifetime mut self` | `self: &'lifetime mut Self`
> **Note**: Lifetimes can be, and usually are, elided with this shorthand.
If the `self` parameter is prefixed with `mut`, it becomes a mutable variable,
similar to regular parameters using a `mut` [identifier pattern]. For example:
```rust
trait Changer: Sized {
fn change(mut self) {}
fn modify(mut self: Box) {}
}
```
As an example of methods on a trait, consider the following:
```rust
# type Surface = i32;
# type BoundingBox = i32;
trait Shape {
fn draw(&self, surface: Surface);
fn bounding_box(&self) -> BoundingBox;
}
```
This defines a trait with two methods. All values that have [implementations]
of this trait while the trait is in scope can have their `draw` and
`bounding_box` methods called.
```rust
# type Surface = i32;
# type BoundingBox = i32;
# trait Shape {
# fn draw(&self, surface: Surface);
# fn bounding_box(&self) -> BoundingBox;
# }
#
struct Circle {
// ...
}
impl Shape for Circle {
// ...
# fn draw(&self, _: Surface) {}
# fn bounding_box(&self) -> BoundingBox { 0i32 }
}
# impl Circle {
# fn new() -> Circle { Circle{} }
# }
#
let circle_shape = Circle::new();
let bounding_box = circle_shape.bounding_box();
```
> **Edition Differences**: In the 2015 edition, it is possible to declare trait
> methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and
> an error as of the 2018 edition. All parameters must have an argument name.
#### Attributes on method parameters
Attributes on method parameters follow the same rules and restrictions as
[regular function parameters].
## Associated Types
*Associated types* are [type aliases] associated with another type. Associated
types cannot be defined in [inherent implementations] nor can they be given a
default implementation in traits.
An *associated type declaration* declares a signature for associated type
definitions. It is written in one of the following forms, where `Assoc` is the
name of the associated type, `Params` is a comma-separated list of type,
lifetime or const parameters, `Bounds` is a plus-separated list of trait bounds
that the associated type must meet, and `WhereBounds` is a comma-separated list
of bounds that the parameters must meet:
```rust,ignore
type Assoc;
type Assoc: Bounds;
type Assoc;
type Assoc: Bounds;
type Assoc where WhereBounds;
type Assoc: Bounds where WhereBounds;
```
The identifier is the name of the declared type alias. The optional trait bounds
must be fulfilled by the implementations of the type alias.
There is an implicit [`Sized`] bound on associated types that can be relaxed using the special `?Sized` bound.
An *associated type definition* defines a type alias for the implementation
of a trait on a type. They are written similarly to an *associated type declaration*,
but cannot contain `Bounds`, but instead must contain a `Type`:
```rust,ignore
type Assoc = Type;
type Assoc = Type; // the type `Type` here may reference `Params`
type Assoc = Type where WhereBounds;
type Assoc where WhereBounds = Type; // deprecated, prefer the form above
```
If a type `Item` has an associated type `Assoc` from a trait `Trait`, then
`- ::Assoc` is a type that is an alias of the type specified in the
associated type definition. Furthermore, if `Item` is a type parameter, then
`Item::Assoc` can be used in type parameters.
Associated types may include [generic parameters] and [where clauses]; these are
often referred to as *generic associated types*, or *GATs*. If the type `Thing`
has an associated type `Item` from a trait `Trait` with the generics `<'a>` , the
type can be named like `::Item<'x>`, where `'x` is some lifetime
in scope. In this case, `'x` will be used wherever `'a` appears in the associated
type definitions on impls.
```rust
trait AssociatedType {
// Associated type declaration
type Assoc;
}
struct Struct;
struct OtherStruct;
impl AssociatedType for Struct {
// Associated type definition
type Assoc = OtherStruct;
}
impl OtherStruct {
fn new() -> OtherStruct {
OtherStruct
}
}
fn main() {
// Usage of the associated type to refer to OtherStruct as ::Assoc
let _other_struct: OtherStruct = ::Assoc::new();
}
```
An example of associated types with generics and where clauses:
```rust
struct ArrayLender<'a, T>(&'a mut [T; 16]);
trait Lend {
// Generic associated type declaration
type Lender<'a> where Self: 'a;
fn lend<'a>(&'a mut self) -> Self::Lender<'a>;
}
impl Lend for [T; 16] {
// Generic associated type definition
type Lender<'a> = ArrayLender<'a, T> where Self: 'a;
fn lend<'a>(&'a mut self) -> Self::Lender<'a> {
ArrayLender(self)
}
}
fn borrow<'a, T: Lend>(array: &'a mut T) -> ::Lender<'a> {
array.lend()
}
fn main() {
let mut array = [0usize; 16];
let lender = borrow(&mut array);
}
```
### Associated Types Container Example
Consider the following example of a `Container` trait. Notice that the type is
available for use in the method signatures:
```rust
trait Container {
type E;
fn empty() -> Self;
fn insert(&mut self, elem: Self::E);
}
```
In order for a type to implement this trait, it must not only provide
implementations for every method, but it must specify the type `E`. Here's an
implementation of `Container` for the standard library type `Vec`:
```rust
# trait Container {
# type E;
# fn empty() -> Self;
# fn insert(&mut self, elem: Self::E);
# }
impl Container for Vec {
type E = T;
fn empty() -> Vec { Vec::new() }
fn insert(&mut self, x: T) { self.push(x); }
}
```
### Relationship between `Bounds` and `WhereBounds`
In this example:
```rust
# use std::fmt::Debug;
trait Example {
type Output: Ord where T: Debug;
}
```
Given a reference to the associated type like `::Output`, the associated type itself must be `Ord`, and the type `Y` must be `Debug`.
### Required where clauses on generic associated types
Generic associated type declarations on traits currently may require a list of
where clauses, dependent on functions in the trait and how the GAT is used. These
rules may be loosened in the future; updates can be found [on the generic
associated types initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/explainer/required_bounds.html).
In a few words, these where clauses are required in order to maximize the allowed
definitions of the associated type in impls. To do this, any clauses that *can be
proven to hold* on functions (using the parameters of the function or trait)
where a GAT appears as an input or output must also be written on the GAT itself.
```rust
trait LendingIterator {
type Item<'x> where Self: 'x;
fn next<'a>(&'a mut self) -> Self::Item<'a>;
}
```
In the above, on the `next` function, we can prove that `Self: 'a`, because of
the implied bounds from `&'a mut self`; therefore, we must write the equivalent
bound on the GAT itself: `where Self: 'x`.
When there are multiple functions in a trait that use the GAT, then the
*intersection* of the bounds from the different functions are used, rather than
the union.
```rust
trait Check {
type Checker<'x>;
fn create_checker<'a>(item: &'a T) -> Self::Checker<'a>;
fn do_check(checker: Self::Checker<'_>);
}
```
In this example, no bounds are required on the `type Checker<'a>;`. While we
know that `T: 'a` on `create_checker`, we do not know that on `do_check`. However,
if `do_check` was commented out, then the `where T: 'x` bound would be required
on `Checker`.
The bounds on associated types also propagate required where clauses.
```rust
trait Iterable {
type Item<'a> where Self: 'a;
type Iterator<'a>: Iterator
- > where Self: 'a;
fn iter<'a>(&'a self) -> Self::Iterator<'a>;
}
```
Here, `where Self: 'a` is required on `Item` because of `iter`. However, `Item`
is used in the bounds of `Iterator`, the `where Self: 'a` clause is also required
there.
Finally, any explicit uses of `'static` on GATs in the trait do not count towards
the required bounds.
```rust
trait StaticReturn {
type Y<'a>;
fn foo(&self) -> Self::Y<'static>;
}
```
## Associated Constants
*Associated constants* are [constants] associated with a type.
An *associated constant declaration* declares a signature for associated
constant definitions. It is written as `const`, then an identifier,
then `:`, then a type, finished by a `;`.
The identifier is the name of the constant used in the path. The type is the
type that the definition has to implement.
An *associated constant definition* defines a constant associated with a
type. It is written the same as a [constant item].
Associated constant definitions undergo [constant evaluation] only when
referenced. Further, definitions that include [generic parameters] are
evaluated after monomorphization.
```rust,compile_fail
struct Struct;
struct GenericStruct;
impl Struct {
// Definition not immediately evaluated
const PANIC: () = panic!("compile-time panic");
}
impl GenericStruct {
// Definition not immediately evaluated
const NON_ZERO: () = if ID == 0 {
panic!("contradiction")
};
}
fn main() {
// Referencing Struct::PANIC causes compilation error
let _ = Struct::PANIC;
// Fine, ID is not 0
let _ = GenericStruct::<1>::NON_ZERO;
// Compilation error from evaluating NON_ZERO with ID=0
let _ = GenericStruct::<0>::NON_ZERO;
}
```
### Associated Constants Examples
A basic example:
```rust
trait ConstantId {
const ID: i32;
}
struct Struct;
impl ConstantId for Struct {
const ID: i32 = 1;
}
fn main() {
assert_eq!(1, Struct::ID);
}
```
Using default values:
```rust
trait ConstantIdDefault {
const ID: i32 = 1;
}
struct Struct;
struct OtherStruct;
impl ConstantIdDefault for Struct {}
impl ConstantIdDefault for OtherStruct {
const ID: i32 = 5;
}
fn main() {
assert_eq!(1, Struct::ID);
assert_eq!(5, OtherStruct::ID);
}
```
[_ConstantItem_]: constant-items.md
[_Function_]: functions.md
[_MacroInvocationSemi_]: ../macros.md#macro-invocation
[_OuterAttribute_]: ../attributes.md
[_TypeAlias_]: type-aliases.md
[_Visibility_]: ../visibility-and-privacy.md
[`Arc`]: ../special-types-and-traits.md#arct
[`Box`]: ../special-types-and-traits.md#boxt
[`Pin
`]: ../special-types-and-traits.md#pinp
[`Rc`]: ../special-types-and-traits.md#rct
[`Sized`]: ../special-types-and-traits.md#sized
[traits]: traits.md
[type aliases]: type-aliases.md
[inherent implementations]: implementations.md#inherent-implementations
[identifier]: ../identifiers.md
[identifier pattern]: ../patterns.md#identifier-patterns
[implementations]: implementations.md
[type]: ../types.md#type-expressions
[constants]: constant-items.md
[constant item]: constant-items.md
[functions]: functions.md
[function item]: ../types/function-item.md
[method call operator]: ../expressions/method-call-expr.md
[path]: ../paths.md
[regular function parameters]: functions.md#attributes-on-function-parameters
[generic parameters]: generics.md
[where clauses]: generics.md#where-clauses
[constant evaluation]: ../const_eval.md