62

When I try to declare a struct inside of another struct:

struct Test {
    struct Foo {}
}

The compiler complains:

error: expected identifier, found keyword `struct`
 --> src/lib.rs:2:5
  |
2 |     struct Foo {}
  |     ^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
  |
2 |     r#struct Foo {}
  |     ^^^^^^^^

error: expected `:`, found `Foo`
 --> src/lib.rs:2:12
  |
2 |     struct Foo {}
  |            ^^^ expected `:`

I could not find any documentation in either direction; are nested structs even supported in Rust?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
abergmeier
  • 13,224
  • 13
  • 64
  • 120
  • 1
    This isn't strictly an answer, but tuples may be defined inside structs, which has some of the similar functionality. Old question, but I figured the information may be relevant. –  Mar 07 '21 at 19:30

3 Answers3

62

No, they are not supported. You should use separate struct declarations and regular fields:

struct Foo {}

struct Test {
    foo: Foo,
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296
  • 18
    Nested structs would e.g. be convenient for visibility of structs. Thus, rust is one of the few classes not supporting nesting. – abergmeier May 13 '14 at 11:21
  • 14
    @abergmeier, Rust's unit of visibility is a module. You should use carefully structured hierarchy of modules to constrain visibility of structs and other things. Also AFAIR you can define functions (this is for certain) and structs and traits (this needs to be verified) inside functions. – Vladimir Matveev May 13 '14 at 11:24
  • Thx. I will see whether structuring via modules fixes visibility issues for me. – abergmeier May 13 '14 at 11:26
1

I found the optional answer for your request. Maybe it can help you: https://internals.rust-lang.org/t/nested-struct-declaration/13314/4

Structural records 592 would give you the nesting (without the privacy controls or naming).

// From the RFC
struct RectangleTidy {
    dimensions: {
        width: u64,
        height: u64,
    },
    color: {
        red: u8,
        green: u8,
        blue: u8,
    },
}

Below is my old answer, please ignore.

Build using the Stable version: 1.65.0. Here's a example for you. rust playground

codes:

#[derive(Debug)]
struct Inner {
    i: i32,
}

#[derive(Debug)]
struct Outer {
    o: i32,
    inner: Inner,
}

pub fn test() {
    // add your code here
    let obj = Outer {
        o: 10,
        inner: Inner { i: 9 },
    };
    assert!(10i32 == obj.o);
    assert!(9i32 == obj.inner.i);
    println!("{}", obj.o);
    println!("{}", obj.inner.i);
    println!("{:?}", obj);
}
fn main() {
    test();
}
0

They are not supported by Rust.

But you can write yourself a proc macro that emulates them. I have, it turns

structstruck::strike!{
    struct Test {
        foo: struct {}
    }
}

into

struct Foo {}
struct Test {
    foo: Foo,
}

You haven't explicitly said so, but I suspect that your goal for using nested structs is not more easily readable data structure declarations, but namespacing? You can't actually have a struct named Test and access Foo as Test::Foo, but you could make yourself a proc macro that at least automatically creates a mod test { Foo {} }.

Caesar
  • 6,733
  • 4
  • 38
  • 44