Defining and Instantiating Structs - The Rust Programming Language (2023)

Structs are similar to tuples, discussed in “The Tuple Type” section, in that both hold multiple related values. Like tuples, thepieces of a struct can be different types. Unlike with tuples, in a structyou’ll name each piece of data so it’s clear what the values mean. Adding thesenames means that structs are more flexible than tuples: you don’t have to relyon the order of the data to specify or access the values of an instance.

To define a struct, we enter the keyword struct and name the entire struct. Astruct’s name should describe the significance of the pieces of data beinggrouped together. Then, inside curly brackets, we define the names and types ofthe pieces of data, which we call fields. For example, Listing 5-1 shows astruct that stores information about a user account.

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn main() {}

Listing 5-1: A User struct definition

To use a struct after we’ve defined it, we create an instance of that structby specifying concrete values for each of the fields. We create an instance bystating the name of the struct and then add curly brackets containing key: value pairs, where the keys are the names of the fields and the values are thedata we want to store in those fields. We don’t have to specify the fields inthe same order in which we declared them in the struct. In other words, thestruct definition is like a general template for the type, and instances fillin that template with particular data to create values of the type. Forexample, we can declare a particular user as shown in Listing 5-2.

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn main() { let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, };}

Listing 5-2: Creating an instance of the Userstruct

To get a specific value from a struct, we use dot notation. For example, toaccess this user’s email address, we use user1.email. If the instance ismutable, we can change a value by using the dot notation and assigning into aparticular field. Listing 5-3 shows how to change the value in the emailfield of a mutable User instance.

(Video) The Rust Programming Language Chapter 5

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn main() { let mut user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; user1.email = String::from("anotheremail@example.com");}

Listing 5-3: Changing the value in the email field of aUser instance

Note that the entire instance must be mutable; Rust doesn’t allow us to markonly certain fields as mutable. As with any expression, we can construct a newinstance of the struct as the last expression in the function body toimplicitly return that new instance.

Listing 5-4 shows a build_user function that returns a User instance withthe given email and username. The active field gets the value of true, andthe sign_in_count gets a value of 1.

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn build_user(email: String, username: String) -> User { User { email: email, username: username, active: true, sign_in_count: 1, }}fn main() { let user1 = build_user( String::from("someone@example.com"), String::from("someusername123"), );}

Listing 5-4: A build_user function that takes an emailand username and returns a User instance

It makes sense to name the function parameters with the same name as the structfields, but having to repeat the email and username field names andvariables is a bit tedious. If the struct had more fields, repeating each namewould get even more annoying. Luckily, there’s a convenient shorthand!

Using the Field Init Shorthand

Because the parameter names and the struct field names are exactly the same inListing 5-4, we can use the field init shorthand syntax to rewritebuild_user so that it behaves exactly the same but doesn’t have therepetition of email and username, as shown in Listing 5-5.

(Video) Rust Programming Tutorial #17 - Structs

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn build_user(email: String, username: String) -> User { User { email, username, active: true, sign_in_count: 1, }}fn main() { let user1 = build_user( String::from("someone@example.com"), String::from("someusername123"), );}

Listing 5-5: A build_user function that uses field initshorthand because the email and username parameters have the same name asstruct fields

Here, we’re creating a new instance of the User struct, which has a fieldnamed email. We want to set the email field’s value to the value in theemail parameter of the build_user function. Because the email field andthe email parameter have the same name, we only need to write email ratherthan email: email.

Creating Instances From Other Instances With Struct Update Syntax

It’s often useful to create a new instance of a struct that includes most ofthe values from another instance, but changes some. You can do this usingstruct update syntax.

First, in Listing 5-6 we show how to create a new User instance in user2regularly, without the update syntax. We set a new value for email butotherwise use the same values from user1 that we created in Listing 5-2.

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn main() { // --snip-- let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; let user2 = User { active: user1.active, username: user1.username, email: String::from("another@example.com"), sign_in_count: user1.sign_in_count, };}

Listing 5-6: Creating a new User instance using one ofthe values from user1

Using struct update syntax, we can achieve the same effect with less code, asshown in Listing 5-7. The syntax .. specifies that the remaining fields notexplicitly set should have the same value as the fields in the given instance.

(Video) Rust Structs, Traits and Impl

struct User { active: bool, username: String, email: String, sign_in_count: u64,}fn main() { // --snip-- let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; let user2 = User { email: String::from("another@example.com"), ..user1 };}

Listing 5-7: Using struct update syntax to set a newemail value for a User instance but use the rest of the values fromuser1

The code in Listing 5-7 also creates an instance in user2 that has adifferent value for email but has the same values for the username,active, and sign_in_count fields from user1. The ..user1 must come lastto specify that any remaining fields should get their values from thecorresponding fields in user1, but we can choose to specify values for asmany fields as we want in any order, regardless of the order of the fields inthe struct’s definition.

Note that the struct update syntax uses = like an assignment; this isbecause it moves the data, just as we saw in the “Ways Variables and DataInteract: Move” section. In this example, we can nolonger use user1 after creating user2 because the String in theusername field of user1 was moved into user2. If we had given user2 newString values for both email and username, and thus only used theactive and sign_in_count values from user1, then user1 would still bevalid after creating user2. The types of active and sign_in_count aretypes that implement the Copy trait, so the behavior we discussed in the“Stack-Only Data: Copy” section would apply.

Using Tuple Structs without Named Fields to Create Different Types

Rust also supports structs that look similar to tuples, called tuplestructs. Tuple structs have the added meaning the struct name provides butdon’t have names associated with their fields; rather, they just have the typesof the fields. Tuple structs are useful when you want to give the whole tuple aname and make the tuple a different type from other tuples, and when naming eachfield as in a regular struct would be verbose or redundant.

To define a tuple struct, start with the struct keyword and the struct namefollowed by the types in the tuple. For example, here we define and usetwo tuple structs named Color and Point:

struct Color(i32, i32, i32);struct Point(i32, i32, i32);fn main() { let black = Color(0, 0, 0); let origin = Point(0, 0, 0);}

Note that the black and origin values are different types, because they’reinstances of different tuple structs. Each struct you define is its own type,even though the fields within the struct might have the same types. Forexample, a function that takes a parameter of type Color cannot take aPoint as an argument, even though both types are made up of three i32values. Otherwise, tuple struct instances are similar to tuples in that you candestructure them into their individual pieces, and you can use a . followedby the index to access an individual value.

(Video) Let's Learn Rust: Structs and Traits

Unit-Like Structs Without Any Fields

You can also define structs that don’t have any fields! These are calledunit-like structs because they behave similarly to (), the unit type thatwe mentioned in “The Tuple Type” section. Unit-likestructs can be useful when you need to implement a trait on some type but don’thave any data that you want to store in the type itself. We’ll discuss traitsin Chapter 10. Here’s an example of declaring and instantiating a unit structnamed AlwaysEqual:

struct AlwaysEqual;fn main() { let subject = AlwaysEqual;}

To define AlwaysEqual, we use the struct keyword, the name we want, then asemicolon. No need for curly brackets or parentheses! Then we can get aninstance of AlwaysEqual in the subject variable in a similar way: using thename we defined, without any curly brackets or parentheses. Imagine that laterwe’ll implement behavior for this type such that every instance ofAlwaysEqual is always equal to every instance of any other type, perhaps tohave a known result for testing purposes. We wouldn’t need any data toimplement that behavior! You’ll see in Chapter 10 how to define traits andimplement them on any type, including unit-like structs.

Ownership of Struct Data

In the User struct definition in Listing 5-1, we used the owned Stringtype rather than the &str string slice type. This is a deliberate choicebecause we want each instance of this struct to own all of its data and forthat data to be valid for as long as the entire struct is valid.

It’s also possible for structs to store references to data owned by somethingelse, but to do so requires the use of lifetimes, a Rust feature that we’lldiscuss in Chapter 10. Lifetimes ensure that the data referenced by a structis valid for as long as the struct is. Let’s say you try to store a referencein a struct without specifying lifetimes, like the following; this won’t work:

Filename: src/main.rs

struct User { active: bool, username: &str, email: &str, sign_in_count: u64,}fn main() { let user1 = User { email: "someone@example.com", username: "someusername123", active: true, sign_in_count: 1, };}

The compiler will complain that it needs lifetime specifiers:

(Video) Visualizing memory layout of Rust's data types

$ cargo run Compiling structs v0.1.0 (file:///projects/structs)error[E0106]: missing lifetime specifier --> src/main.rs:3:15 |3 | username: &str, | ^ expected named lifetime parameter |help: consider introducing a named lifetime parameter |1 ~ struct User<'a> {2 | active: bool,3 ~ username: &'a str, |error[E0106]: missing lifetime specifier --> src/main.rs:4:12 |4 | email: &str, | ^ expected named lifetime parameter |help: consider introducing a named lifetime parameter |1 ~ struct User<'a> {2 | active: bool,3 | username: &str,4 ~ email: &'a str, |For more information about this error, try `rustc --explain E0106`.error: could not compile `structs` due to 2 previous errors

In Chapter 10, we’ll discuss how to fix these errors so you can storereferences in structs, but for now, we’ll fix errors like these using ownedtypes like String instead of references like &str.

FAQs

How do you define a struct in Rust? ›

To define a struct, we enter the keyword struct and name the entire struct. A struct's name should describe the significance of the pieces of data being grouped together. Then, inside curly brackets, we define the names and types of the pieces of data, which we call fields.

How do you define a struct? ›

Structures (also called structs) are a way to group several related variables into one place. Each variable in the structure is known as a member of the structure. Unlike an array, a structure can contain many different data types (int, float, char, etc.).

Are structs like classes Rust? ›

In languages like C, Go, and Rust, classes are not a feature. Instead, these languages use structs, which define only a group of properties. While structs don't allow you to define methods, both Rust and Go define functions in a way that provides access to structs.

How do you pass a struct to a function in Rust? ›

We can pass a struct to a function by specifying the struct name as the type in the parameter list. We can return a struct from a function by specifying the struct name as the return type. We can define functions that are specific to a struct, called methods, that can only be used by instances of that struct.

How do you create a struct? ›

Create struct Variables

When a struct type is declared, no storage or memory is allocated. To allocate memory of a given structure type and work with it, we need to create variables. Another way of creating a struct variable is: struct Person { // code } person1, person2, p[20];

What is a struct element? ›

A struct in the C programming language (and many derivatives) is a composite data type (or record) declaration that defines a physically grouped list of variables under one name in a block of memory, allowing the different variables to be accessed via a single pointer or by the struct declared name which returns the ...

What is struct data type? ›

A struct data type represents a collection of elements of different data types. A struct data type has an associated schema that defines the structure of the data. To pass, generate, or process struct data, assign struct data type to ports.

Can I define struct in a function? ›

No, you can't. Structs can only contain variables inside, storing function pointers inside the struct can give you the desired result.

Where are struct used? ›

'Struct' keyword is used to create a structure. A structure can contain variables, methods, static constructor, parameterized constructor, operators, indexers, events, and property. A structure can not derive/inherit from any structure or class. A structure can implement any number of interfaces.

What is the type of struct Rust? ›

Structs in Rust come in three flavors: Structs with named fields, tuple structs, and unit structs. Regular structs are the most commonly used. Each field defined within them has a name and a type, and once defined can be accessed using example_struct.

What is Rust used for? ›

Rust is a low-level programming language with direct access to hardware and memory, which makes it a great solution for embedded and bare-metal development. You can use Rust to write operation systems or microcontroller applications.

Why Rust is the future? ›

Rust is the only 'safe' language which is also as fast as the native languages. That's it's key selling point. That's desirable for native developers since it's safer, and it's desirable for managed developers because it produces software that is faster and uses less memory.

Can a struct have private members? ›

Class members, including nested classes and structs, can be public , protected internal , protected , internal , private protected , or private . Class and struct members, including nested classes and structs, have private access by default.

How do you pass a struct in a function? ›

Passing of structure to the function can be done in two ways: By passing all the elements to the function individually. By passing the entire structure to the function.

Are struct members public by default? ›

A structure is a class defined with the struct keyword. Its members and base classes are public by default. In practice, structs are typically reserved for data without functions. When deriving a struct from a class/struct, default access-specifier for a base class/struct is public.

Can you initialize a struct? ›

When initializing a struct, the first initializer in the list initializes the first declared member (unless a designator is specified) (since C99), and all subsequent initializers without designators (since C99)initialize the struct members declared after the one initialized by the previous expression.

How can struct be instantiated? ›

When you create a struct object using the New operator, it gets created and the appropriate constructor is called. Unlike classes, structs can be instantiated without using the New operator. If the New operator is not used, the fields remain unassigned and the object cannot be used until all the fields are initialized.

What is struct in database? ›

Struct types are extended object-relational data-types supported by some databases. Struct types are user define types in the database such as OBJECT types on Oracle. Structs normally contain Arrays ( VARRAY ) or other Struct types, and can be stored in a column or a table.

Why we are using struct? ›

Use a struct when you need to store elements of different data types under one data type. C++ structs are a value type rather than being a reference type. Use a struct if you don't intend to modify your data after creation.

What is a structure name? ›

A "structure declaration" names a type and specifies a sequence of variable values (called "members" or "fields" of the structure) that can have different types. An optional identifier, called a "tag," gives the name of the structure type and can be used in subsequent references to the structure type.

Why struct node is used? ›

struct node * , is a pointer to an element of a structure node. It basically stores the address of any variable of type 'node' ( A custom structure ). You must also have a structure like this in your program: struct node { int info; struct node* next; }; Using struct is necessary before node* to comply with C syntax.

Where is struct stored in memory? ›

If you create a struct as a function-local variable, its memory will be allocated on the stack. If the struct instance is a class member variable, its memory will be allocated contiguously as part of the class instance's memory on the heap.

How is data stored in a struct? ›

The members are stored in order, with padding inserted where necessary to correctly align each member relative to the start of the structure. Some compilers have a non-standard extension to "pack" the members, so that padding is not inserted.

How a struct is stored in memory? ›

Struct members are stored in the order they are declared. (This is required by the C99 standard, as mentioned here earlier.) If necessary, padding is added between struct members, to ensure that the latter one uses the correct alignment. Each primitive type T requires an alignment of sizeof(T) bytes.

Where should struct be defined? ›

If the struct is to be used by other compilation units (. c files) , place it in the header file so you can include that header file wherever it is needed. If the struct is only used in one compilation unit (. c file), you place it in that .

Can we define class with struct? ›

Yes you can. In c++, class and struct are kind of similar. We can define not only structure inside a class, but also a class inside one.

Can a struct declare properties? ›

A struct can contain properties, auto-implemented properties, methods, etc., same as classes. The following struct includes the static method.

Why struct is stored on the stack? ›

Most importantly, a struct unlike a class, is a value type. So, while instances of a class are stored in the heap, instances of a struct are stored in the stack. When an instance of a struct is passed to a method, it is always passed by value.

What is purpose of struct class? ›

Classes and structs are the constructs whereby you define your own types. Classes and structs can both contain data members and member functions, which enable you to describe the type's state and behavior.

What programming language uses struct? ›

A struct (short for structure) is a data type available in C programming languages, such as C, C++, and C#. It is a user-defined data type that can store multiple related items. A struct variable is similar to a database record since it may contain multiple data types related to a single entity.

What is data type in Rust? ›

Rust has four primary scalar types: integers, floating-point numbers, Booleans, and characters.

What is unit type in Rust? ›

The () type, also called “unit”. The () type has exactly one value () , and is used when there is no other meaningful value that could be returned.

What is type keyword in Rust? ›

Keyword type

Define an alias for an existing type. The syntax is type Name = ExistingType; .

Is Rust a frontend or backend? ›

Rust is a backend development language that performs very close to C/C++ and solves another headache of C/C++ developers that is Memory Management. Rust is being used by many big companies like AWS, Cloudflare, Next. js, etc.

Why is Rust so important? ›

Rust helps developers avoid a host of memory-related flaws common to C/C++, which ultimately cost organizations in security updates. The language got its most high-profile support when Microsoft revealed it was experimenting with it for Windows, chiefly to dodge memory bugs.

Is Rust easy to learn? ›

Rust is considered difficult to learn by many people. Indeed, when I learned it, I considered it to be the hardest programming language up to that time I've met. And that says something, since I have a habit of learning whatever language I find interesting.

Is it worth learning Rust in 2022? ›

RUST is an excellent language to learn in 2022. It is fast, safe, concurrent, and portable. It also has great tooling and a thriving community. If you are looking for a systems programming language, RUST is the perfect choice.

Is Rust better than Python? ›

Rust is a go-to language when performance matters because it works well for processing large amounts data. It can handle CPU-intensive operations like executing algorithms, which is why Rust is more suitable than Python for systems development.

How much do Rust developers make? ›

Average salary and compensation

The average salary for a rust developer is $102,100 in the United States.

Should I define structs in header or source? ›

If the struct is to be used by other compilation units (. c files) , place it in the header file so you can include that header file wherever it is needed. If the struct is only used in one compilation unit (. c file), you place it in that .

Do you define structs in header files? ›

For a structure definition that is to be used across more than one source file, you should definitely put it in a header file.

How do you define a struct in CPP? ›

The struct keyword defines a structure type followed by an identifier (name of the structure). Then inside the curly braces, you can declare one or more members (declare variables inside curly braces) of that structure. For example: struct Person { char name[50]; int age; float salary; };

What is struct syntax? ›

Syntax to Define a Structure in C

structName: This is the name of the structure which is specified after the keyword struct. data_Type: The data type indicates the type of the data members of the structure. A structure can have data members of different data types.

Do you need to initialize a struct? ›

If you want to create an object using your struct as its blueprint, you must first “initialize” the struct. To “initialize a struct is to create an actual object based on the struct (a blueprint) that you can then use.

Is struct private or public by default? ›

In a struct, members default to public. In a class, members default to private.

Can you define a struct inside main? ›

Note that, if we define the structure inside the main function, then it can not be passed to the functions; i.e. Lines 7-12 of Listing 6.6 can not be defined inside the main function, as it will generate error.

Where struct is stored? ›

Most importantly, a struct unlike a class, is a value type. So, while instances of a class are stored in the heap, instances of a struct are stored in the stack. When an instance of a struct is passed to a method, it is always passed by value.

Are structs stored in memory? ›

Structs and classes are data types, so they don't occupy memory at runtime. Structs and classes are really compile-time things, not runtime things. Objects (variables) of those data types do occupy memory.

Can we define struct in class? ›

Yes you can. In c++, class and struct are kind of similar. We can define not only structure inside a class, but also a class inside one. It is called inner class.

Can we define constructor in struct? ›

This will generate an error in C but not in C++. 3. Constructor creation in structure: Structures in C cannot have a constructor inside a structure but Structures in C++ can have Constructor creation.

Why do we need struct? ›

In C#, a structure is a value type data type. It helps you to make a single variable hold related data of various data types. The struct keyword is used for creating a structure.

Videos

1. 05 Structs and Methods | Rust Tutorials
(Jeff No Zhao)
2. 9. Structs
(300 seconds of Rust)
3. Smart Rust: Introduction to structs
(IDG TECHtalk)
4. Chapter 6 - Structures - Rust Crash Course 🦀
(Vandad Nahavandipoor)
5. Using Structs to Structure Related Data - Rust
(danlogs)
6. Introduction to Rust: 2.3 - Collections and Structs
(Hitchcock Codes)
Top Articles
Latest Posts
Article information

Author: Rev. Leonie Wyman

Last Updated: 03/29/2023

Views: 6086

Rating: 4.9 / 5 (79 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Rev. Leonie Wyman

Birthday: 1993-07-01

Address: Suite 763 6272 Lang Bypass, New Xochitlport, VT 72704-3308

Phone: +22014484519944

Job: Banking Officer

Hobby: Sailing, Gaming, Basketball, Calligraphy, Mycology, Astronomy, Juggling

Introduction: My name is Rev. Leonie Wyman, I am a colorful, tasty, splendid, fair, witty, gorgeous, splendid person who loves writing and wants to share my knowledge and understanding with you.