Skip to content

iAmMichaelConnor/rust-cheatsheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

rust-cheatsheet

This has been sitting on my laptop for ages. It's a collation of all the rust syntax that confused me when I first read the rust book. Hope people find it useful!


struct StructName<T> {
  ...
}

impl<T> StructName<T> {
  ...
  // implement methods/assoc_funcs for this struct which are generic over all types.
}

impl<T: Trait1 + Trait2> StructName<T> {
  ...
  // implement methods/assoc_funcs for this struct which are generic ONLY over types which implement both traits 1 and 2.
}

// conditionally implementing a trait:
impl<T: IfItAlreadyImplementsThisTrait> AlsoImplementThisTrait for T {}

trait TraitName {
  fn method_name(&self) -> SomeTypeName; // we could include a default function implementation body here, as well.

  fn assoc_func_name() -> Self; // usually returns an instance of the type. we could include a default function implementation body here, as well.
}

impl TraitName for TypeName {
  fn method_name(&self) -> SomeTypeName {
    ...
  }

  fn assoc_func_name() -> Self {
    ...
  }
}

impl TraitName for OtherTypeName {} // empy block means "use the default" (as specified in the trait definition)

--

trait TraitName<T=DefaultType> {
  ...
}

struct TypeName1
struct TypeName2

impl TraitName for TypeName1 {
  // defaults to using the DefaultType
}

impl TraitName<ConcreteType> for TypeName2 {
  // uses the specified type
}

Putting a lot of it together:

struct StructName<T> {
  ...
}

trait TraitName<U=DefaultType> {
  ...
}

impl<T> TraitName<ConcreteType> for StructName<T> {
  ...
  // implement methods/assoc_funcs for this struct which are generic over all types.
  // methods/assoc_funcs might refer to the specified ConcreteType (rather than the DefaultType) too
}

impl<T: Trait1 + Trait2> TraitName<ConcreteType> for StructName<T> {
  ...
  // implement methods/assoc_funcs for this struct which are generic ONLY over types which implement both traits 1 and 2.
  // methods/assoc_funcs might refer to the specified ConcreteType (rather than the DefaultType) too
}

// conditionally implementing a trait:
impl<T: IfItAlreadyImplementsThisTrait> AlsoImplementThisTrait<ConcreteType> for T {}

// grouped function signatures achieve the same thing:

fn func_name(param: impl TraitName) {}
fn func_name<T: TraitName>(param: T) {}

fn func_name(param1: impl Trait1, param2: impl Trait2) {}

fn func_name<T: TraitName>(param1: T, param2: T) {}

fn func_name(param: impl Trait1 + Trait2) {}
fn func_name<T: Trait1 + Trait2>(param: T) {}
fn func_name<T>(param: T) -> ReturnType
  where T: Trait1 + Trait2
{
...
}

fn func_name<T: Trait1 + Trait2, U: Trait3 + Trait4>(t: T, u: U) {}
fn func_name<T, U>(t: T, u: U) -> ReturnType
  where T: Trait1 + Trait2
        U: Trait3 + Trait4
{
...
}

// return a Type that implements a particular Trait:
fn func_name() -> impl TraitName {}

trait TraitName {
  type AssocTypeName; // associated type placeholder name

  // add function signatures of methods and assoc functions which refer to AssocTypeName
}

impl TraitName for SomeTypeName {
  type AssocTypeName = ConcreteType; // e.g. u32

  // add implementations of methods and functions which work with AssocTypeName as u32 (or whichever ConcreteType is specified)
}

trait TraitName {
  type AssocTypeName: Trait1; // associated type placeholder name, where the type must implement Trait1

  // add function signatures of methods and assoc functions which refer to AssocTypeName
}

impl TraitName for SomeTypeName {
  type AssocTypeName = ConcreteType; // where the ConcreteType must implement Trait1

  // add implementations of methods and functions which work with AssocTypeName as ConcreteType
}

trait TraitName<T> {
  // add function signatures of methods and assoc functions which refer to T
}

impl<ConcreteType1> TraitName<ConcreteType1> for SomeType {
  // add implementations of methods and functions which work with ConcreteType1
}

impl<ConcreteType2> TraitName<ConcreteType2> for SomeType {
  // add implementations of methods and functions which work with ConcreteType2
}

trait TraitName: SuperTraitName {
  ...
}

// ^^ each time we implement this trait for some type, we must also implement the supertrait for that type too! This trait's methods _depend_ on the supertrait in some way.

Calling a method or associated function on an instance of a type:

let instance: TypeName = ...
instance.method_name(); // calls a method

TraitName::method_name(&instance); // also calls a method in the same way. Disambiguates if multiple traits have the same method name.

<TypeName as TraitName>::method_name(instance, arg1, ...); // calls a method. Disambiguates when multiple types have traits which include this method name. I.e. when multiple impl blocks have the same function name.

<TypeName as TraitName>::assoc_func_name(arg1, ...); // calls an associated function. Disambiguates same as above.

use path::to::ExternalTraitName;

for<'a> can be read as "for all choices of 'a" - it is an example of a Higher-Ranked Trait Bound (HRTB) - and basically produces an infinite list of trait bounds that must be satisfied

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published