Bird
Raised Fist0
Rustprogramming~5 mins

Generic structs in Rust

Choose your learning style10 modes available
Introduction

Generic structs let you create flexible data containers that can hold any type of data. This helps you reuse code without repeating it for each data type.

When you want a struct to work with different types of data without rewriting it.
When you have a collection or container that can hold various data types.
When you want to write functions or methods that work with many types inside a struct.
When you want to keep your code clean and avoid duplication for similar structs with different types.
Syntax
Rust
struct StructName<T> {
    field: T,
}

The <T> after the struct name means it uses a generic type called T.

You can use any name instead of T, but T is common and stands for 'Type'.

Examples
A struct Point that can hold any type for x and y.
Rust
struct Point<T> {
    x: T,
    y: T,
}
A struct with two different generic types T and U.
Rust
struct Pair<T, U> {
    first: T,
    second: U,
}
Creating a Point with integers.
Rust
let int_point = Point { x: 5, y: 10 };
Creating a Point with floating-point numbers.
Rust
let float_point = Point { x: 1.2, y: 3.4 };
Sample Program

This program creates two Point structs with different types: integers and floats. It then prints their values.

Rust
struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let int_point = Point { x: 5, y: 10 };
    let float_point = Point { x: 1.2, y: 3.4 };

    println!("int_point: x = {}, y = {}", int_point.x, int_point.y);
    println!("float_point: x = {}, y = {}", float_point.x, float_point.y);
}
OutputSuccess
Important Notes

Generic structs help avoid writing many similar structs for different types.

You can add methods to generic structs using impl<T> StructName<T>.

Rust checks types at compile time, so using generics is safe and efficient.

Summary

Generic structs let you create flexible containers for any data type.

Use <T> after the struct name to define a generic type.

They help keep your code clean and reusable.

Practice

(1/5)
1. What does the <T> mean in the definition of a generic struct in Rust?
easy
A. It specifies a fixed type that the struct must always use.
B. It declares a placeholder type that can be replaced with any type when used.
C. It is used to define a function inside the struct.
D. It marks the struct as unsafe to use.

Solution

  1. Step 1: Understand generic type parameters

    The <T> syntax declares a generic type parameter named T, which acts as a placeholder for any type.
  2. Step 2: Recognize its purpose in structs

    This allows the struct to be flexible and work with any data type specified when creating an instance.
  3. Final Answer:

    It declares a placeholder type that can be replaced with any type when used. -> Option B
  4. Quick Check:

    Generic type parameter = placeholder type [OK]
Hint: Generic <T> means flexible type placeholder [OK]
Common Mistakes:
  • Thinking <T> fixes the type permanently
  • Confusing <T> with function syntax
  • Assuming <T> makes the struct unsafe
2. Which of the following is the correct syntax to define a generic struct named Container with one generic type parameter T?
easy
A. struct Container<T> { value: T }
B. struct Container { T value }
C. struct Container<T> (value: T);
D. struct Container<T> = { value: T };

Solution

  1. Step 1: Recall Rust struct syntax with generics

    Generic structs use struct Name<T> { field: T } syntax.
  2. Step 2: Check each option

    struct Container<T> { value: T } matches the correct syntax with curly braces and generic parameter T. Options A, B, and D have syntax errors or wrong struct declaration styles.
  3. Final Answer:

    struct Container<T> { value: T } -> Option A
  4. Quick Check:

    Correct generic struct syntax = struct Container<T> { value: T } [OK]
Hint: Use struct Name<T> { field: T } for generic structs [OK]
Common Mistakes:
  • Omitting angle brackets around T
  • Using parentheses instead of braces
  • Trying to assign struct with '='
3. What will be the output of this Rust code?
struct Pair<T> {
    first: T,
    second: T,
}

fn main() {
    let pair = Pair { first: 5, second: 10 };
    println!("{} and {}", pair.first, pair.second);
}
medium
A. 5 and 10
B. Pair { first: 5, second: 10 }
C. Compilation error due to missing type annotation
D. Runtime error

Solution

  1. Step 1: Understand struct instantiation with generics

    The struct Pair is instantiated with integers 5 and 10, so T is inferred as i32.
  2. Step 2: Analyze the println! macro output

    The macro prints the values of pair.first and pair.second separated by " and ".
  3. Final Answer:

    5 and 10 -> Option A
  4. Quick Check:

    Printing struct fields = 5 and 10 [OK]
Hint: Generic type inferred from values; prints fields directly [OK]
Common Mistakes:
  • Expecting struct debug print without {:?}
  • Thinking type annotation is mandatory here
  • Assuming runtime error without reason
4. Identify the error in this generic struct code and choose the fix:
struct Wrapper<T> {
    value: T
}

fn main() {
    let w: Wrapper = Wrapper { value: 42 };
}
medium
A. Wrapper struct must have a lifetime parameter
B. Missing semicolon after struct field declaration
C. Cannot assign integer to generic type T
D. Missing generic type parameter in variable declaration: use Wrapper<i32>

Solution

  1. Step 1: Check struct usage with generics

    The variable w is declared as Wrapper without specifying the generic type <T>, which is required.
  2. Step 2: Fix by specifying the type

    Adding <i32> to Wrapper in the declaration fixes the error: let w: Wrapper<i32> = ....
  3. Final Answer:

    Missing generic type parameter in variable declaration: use Wrapper<i32> -> Option D
  4. Quick Check:

    Specify generic type when declaring variables [OK]
Hint: Always specify generic type when declaring variables [OK]
Common Mistakes:
  • Forgetting to add <T> in variable type
  • Thinking semicolon is missing after field
  • Assuming lifetime needed without context
5. Given this generic struct and function, what is the output?
struct Container<T> {
    item: T,
}

impl<T> Container<T> {
    fn new(item: T) -> Self {
        Container { item }
    }

    fn describe(&self) -> String {
        match &self.item {
            i if i.is::<i32>() => "Integer container".to_string(),
            _ => "Other container".to_string(),
        }
    }
}

fn main() {
    let c = Container::new(100);
    println!("{}", c.describe());
}
hard
A. Integer container
B. Other container
C. Compilation error due to is::<i32>() usage
D. Runtime panic

Solution

  1. Step 1: Analyze the use of is::<i32>() in match

    The method is::<i32>() does not exist on generic references in Rust; this causes a compilation error.
  2. Step 2: Understand Rust type checking limitations

    Rust does not support runtime type checking like is::<i32>() on generic types without special traits or macros.
  3. Final Answer:

    Compilation error due to is::<i32>() usage -> Option C
  4. Quick Check:

    Rust generics lack runtime type checks like is::<Type>() [OK]
Hint: Rust generics can't check type at runtime without traits [OK]
Common Mistakes:
  • Assuming is::<Type>() works on generics
  • Expecting output without compilation errors
  • Ignoring Rust's static typing rules
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard