Traits

A trait describes an abstract interface that types can implement. This interface consists of an interface surface of associated items, along with methods.

trait Trait {
    fn fn_sig(self, b: Self) -> bool;
} {
    fn method(self, b: Self) -> bool {
        true
    }
}

Associated items come in two varieties:

All traits define an implicit type parameter Self that refers to "the type that is implementing this interface". Traits may also contain additional type parameters. These type parameters, including Self, may be constrained by other traits and so forth as usual.

Traits are implemented for specific types through separate implementations.

Associated functions

Trait functions consist of just a function signature. This indicates that the implementation must define the function.

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.

Associated constants examples

script;

trait T {
    const C: bool;
}

struct S {}

impl T for S {
    const C: bool = true;
}

fn main() -> bool {
    let s = S {};
    S::C
}

Associated constants may omit the equals sign and expression to indicate implementations must define the constant value.

Associated types

Associated types in Sway allow you to define placeholder types within a trait, which can be customized by concrete implementations of that trait. These associated types are used to specify the return types of trait methods or to define type relationships within the trait.

Associated types examples

script;

trait TypeTrait {
    type T;

    fn method(self, s1: Self::T) -> Self::T;
}

struct Struct {}

struct Struct2 {}

impl TypeTrait for Struct2 {
  type T = Struct;

  fn method(self, s1: Self::T) -> Self::T {
    s1
  }
}

fn main() -> u32 {
  Struct2{}.method(Struct{});

  1
}