Structs
A struct is defined using the struct keyword.
struct_def = [ "pub" ] "struct" IDENT "{" [ struct_fields ] "}" ;
struct_fields = struct_field { "," struct_field } [ "," ] ;
struct_field = [ "pub" ] IDENT ":" type ;
Struct Definition
Field names MUST be unique within a struct.
struct Point {
x: i32,
y: i32,
}
Struct Instantiation
All fields MUST be initialized when creating a struct instance.
Field initializers MAY be provided in any order.
struct Point { x: i32, y: i32 }
fn main() -> i32 {
// Fields can be initialized in any order
let p = Point { y: 20, x: 10 };
p.x + p.y
}
Struct Usage
Struct fields are accessed using dot notation.
Mutable struct values allow field reassignment.
struct Counter { value: i32 }
fn main() -> i32 {
let mut c = Counter { value: 0 };
c.value = c.value + 1;
c.value
}
Field Visibility
(ADR-0073.) A field declaration MAY be prefixed with the pub keyword. A field marked pub is accessible from any module that can name the enclosing struct. A field without pub is accessible only from within the same module as the struct definition (per the same module-equivalence rule used by item visibility in ADR-0026).
Field access (expr.field), field assignment (lhs.field = rhs), struct literal construction (T { field: ... }), and pattern matching that mentions a field by name (T { field, .. }) are all subject to the same visibility check.
Wildcard struct patterns (T { .. }) and patterns that do not name a particular field do not constitute access to that field and require no visibility privilege.
// in module a/lib.gruel
pub struct Account {
pub id: u64,
balance: i64, // module-private
}
// in module b/main.gruel
const a = @import("a/lib.gruel");
fn main() -> i32 {
let acc = a.Account { id: 1, balance: 0 }; // ERROR: `balance` is private
acc.balance // ERROR: `balance` is private
}