70

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?

1
  • 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. Commented Mar 7, 2021 at 19:30

4 Answers 4

73

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

struct Foo {}

struct Test {
    foo: Foo,
}
Sign up to request clarification or add additional context in comments.

3 Comments

Nested structs would e.g. be convenient for visibility of structs. Thus, rust is one of the few classes not supporting nesting.
@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.
Thx. I will see whether structuring via modules fixes visibility issues for me.
5

I found a discussion regarding this topic, maybe it can help you: https://internals.rust-lang.org/t/nested-struct-declaration/13314/4

RFC Structural records 592 was discussing the nesting (without the privacy controls or naming), but was ultimately rejected.

// From the RFC (not working as of Rust 1.81.0 in 2024)
struct RectangleTidy {
    dimensions: {
        width: u64,
        height: u64,
    },
    color: {
        red: u8,
        green: u8,
        blue: u8,
    },
}

Below is my old answer, which is the current way to solve it.

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();
}

2 Comments

op asked if it was possible define a structure inside another one, not how to declare a property that has a struct type.
@klefevre You're right. Thank you for reminder. I made a mistake here.
1

You can use nestify:

[dependencies]
nestify = "0.3"
nestify::nest! {
    #[derive(Debug)] struct Root {
        a: #[derive(Debug)] struct A {
            text: String,
        },
        b: #[derive(Debug)] struct B {
            text: String,
        },
    }
}

Or you can implement one yourself:

macro_rules! nstruct {
    (
        $name:ident {
            $(
                $field_name:ident : $field_ty:ident $({
                    $($field_ty_inner:tt)*
                })?
            ),*
        $(,)? }
    ) => {
        #[derive(Debug)]
        struct $name {
            $(
                $field_name : $field_ty
            ),*
        }

        $(nstruct! {
            $field_ty $({
                $($field_ty_inner)*
            })?
        })*
    };

    ($name:ident {$($fields:tt)*}) => {
        nstruct! {
            struct $name {
                $($fields)*
            }
        }
    };

    ($name:ident) => {};
}


nstruct! {
    Root {
        a: A {
            text: String,
        },
        b: B {
            text: String,
        }
    }
}

Comments

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 {} }.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.