Skip to content

Latest commit

 

History

History
211 lines (178 loc) · 6.09 KB

types.md

File metadata and controls

211 lines (178 loc) · 6.09 KB

{{#include types-redirect.html}}

Types

r[type]

r[type.intro] Every variable, item, and value in a Rust program has a type. The type of a value defines the interpretation of the memory holding it and the operations that may be performed on the value.

r[type.builtin] Built-in types are tightly integrated into the language, in nontrivial ways that are not possible to emulate in user-defined types.

r[type.user-defined] User-defined types have limited capabilities.

r[type.kinds] The list of types is:

Type expressions

r[type.name]

r[type.name.syntax]

Syntax
Type :
      TypeNoBounds
   | ImplTraitType
   | TraitObjectType

TypeNoBounds :
      ParenthesizedType
   | ImplTraitTypeOneBound
   | TraitObjectTypeOneBound
   | TypePath
   | TupleType
   | NeverType
   | RawPointerType
   | ReferenceType
   | ArrayType
   | SliceType
   | InferredType
   | QualifiedPathInType
   | BareFunctionType
   | MacroInvocation

r[type.name.intro] A type expression as defined in the Type grammar rule above is the syntax for referring to a type. It may refer to:

r[type.name.sequence]

r[type.name.path]

r[type.name.pointer]

r[type.name.inference]

  • The inferred type which asks the compiler to determine the type.

r[type.name.grouped]

r[type.name.trait]

r[type.name.never]

r[type.name.macro-expansion]

  • Macros which expand to a type expression.

Parenthesized types

r[type.name.parenthesized]

r[type.name.parenthesized.syntax]

ParenthesizedType :
   ( Type )

r[type.name.parenthesized.intro] In some situations the combination of types may be ambiguous. Use parentheses around a type to avoid ambiguity. For example, the + operator for type boundaries within a reference type is unclear where the boundary applies, so the use of parentheses is required. Grammar rules that require this disambiguation use the TypeNoBounds rule instead of Type.

# use std::any::Any;
type T<'a> = &'a (dyn Any + Send);

Recursive types

r[type.recursive]

r[type.recursive.intro] Nominal types — structs, enumerations, and unions — may be recursive. That is, each enum variant or struct or union field may refer, directly or indirectly, to the enclosing enum or struct type itself.

r[type.recursive.constraint] Such recursion has restrictions:

  • Recursive types must include a nominal type in the recursion (not mere type aliases, or other structural types such as arrays or tuples). So type Rec = &'static [Rec] is not allowed.
  • The size of a recursive type must be finite; in other words the recursive fields of the type must be pointer types.

An example of a recursive type and its use:

enum List<T> {
    Nil,
    Cons(T, Box<List<T>>)
}

let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));