Skip to content
This guide targets Fe 26.5. Fe is not production-ready. Install Fe 26.5

Struct Definition

Structs are custom data types that group related values together. They’re one of Fe’s primary tools for organizing data and behavior.

Define a struct with the struct keyword:

struct Point {
x: u256,
y: u256,
}

Each field has a name and a type, separated by a colon.

By default, struct fields are private. Use pub to make them publicly accessible:

struct Token {
pub name: String, // Public - accessible from outside
pub symbol: String, // Public
pub decimals: u8, // Public
internal_id: u256, // Private - only accessible within the module
}

Make the entire struct public with pub struct:

pub struct TokenInfo {
pub name: String,
pub total_supply: u256,
}

A pub struct can be used by other modules, but its fields still need individual pub modifiers to be accessible.

Create struct instances using struct literal syntax:

let point = Point { x: 10, y: 20 }

All fields must be provided:

let rect = Rectangle {
width: 100,
height: 50,
}

Access fields with dot notation:

let p = Point { x: 10, y: 20 }
let x_value = p.x // 10
let y_value = p.y // 20

Structs are immutable by default. To modify, use mut:

var p = Point { x: 10, y: 20 }
p.x = 30 // Now p is { x: 30, y: 20 }

Structs can contain other structs:

struct Bounds {
min: Point,
max: Point,
}
let bounds = Bounds {
min: Point { x: 0, y: 0 },
max: Point { x: 100, y: 100 },
}
let min_x = bounds.min.x // 0

Structs can hold any Fe type:

struct GameState {
score: u256,
position: (u256, u256), // Tuple
active: bool,
}
struct Registry {
entries: StorageMap<u256, u256>, // For storage structs
count: u256,
}

Extract fields with pattern matching:

// Destructure into variables
let Point { x, y } = Point { x: 10, y: 20 }
// Rename during destructuring
let Point { x: horizontal, y: vertical } = Point { x: 10, y: 20 }
// Partial destructuring
let Point { x, .. } = Point { x: 10, y: 20 }

A tuple struct has positional fields instead of named ones. It is a lightweight way to write a newtype, a distinct type that wraps another one:

pub struct Month(pub u8)
pub struct Pair<T>(pub T, pub T)
fn days_in(_ month: Month) -> u8 {
match month {
Month(2) => 28,
Month(4) | Month(6) | Month(9) | Month(11) => 30,
_ => 31,
}
}
#[test]
fn tuple_structs() {
var m = Month(10)
m.0 = 11
assert!(days_in(m) == 30)
let Month(raw) = m
assert!(raw == 11)
let p = Pair<u256>(1, 2)
assert!(p.0 + p.1 == 3)
}

Construct a tuple struct by calling its name like a function, access fields by position (m.0), and destructure it with a tuple pattern. Fields are private unless marked pub. Tuple structs can be generic and can be used as contract storage fields, but #[event], #[error] and #[abi] require named fields.

An important distinction in Fe:

FeatureStructsContracts
Fields✓✓
Impl blocks✓✗
Methods✓✗
Init block✗✓
Recv blocks✗✓

Structs are for data and behavior. Contracts are for on-chain state and message handling.

SyntaxDescription
struct Name { }Define a struct
pub structPublic struct
pub field: TypePublic field
Name { field: value }Create instance
instance.fieldAccess field
let Name { field } = instanceDestructure
struct Name(pub T)Tuple struct
Name(value), instance.0Create / access a tuple struct