Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to create a new generic struct?

I'm trying to make a generic struct that can be initialized to something of type T. It looks like this:

pub struct MyStruct<T> {
    test_field: Option<T>,
    name: String,
    age: i32,
}

impl MyStruct<T> {
    fn new(new_age: i32, new_name: String) -> MyStruct<T> {
        MyStruct<T> {
            test_field: None,
            age: new_age,
            name: new_name,
        }
    }
}

This doesn't seem to work. Among other errors, I get:

error: chained comparison operators require parentheses
 --> src/lib.rs:9:17
  |
9 |         MyStruct<T> {
  |                 ^^^^^
  |
like image 751
Steve Avatar asked May 22 '15 14:05

Steve


People also ask

Can struct be generic?

In addition to generic classes, you can also create a generic struct. Like a class, the generic struct definition serves as a sort of template for a strongly-typed struct. When you declare a variable of this struct type, you provide a type for its generic parameter.

How do generics work in Rust?

In Rust, generics refer to the parameterization of data types and traits. Generics allows to write more concise and clean code by reducing code duplication and providing type-safety. The concept of Generics can be applied to methods, functions, structures, enumerations, collections and traits.

Can struct have generic C#?

Classes, structs, and interfaces can all be generic, as can delegates, which we'll be looking at in Chapter 9. Example 4-1 shows how to define a generic class. The syntax for structs and interfaces is much the same: the type name is followed immediately by a type parameter list.


1 Answers

I highly recommend reading The Rust Programming Language. It covers basics like this, and the Rust team spent a lot of time to make it good! Specifically, the section on generics would probably have helped here.

You don't need to use <T> when instantiating the struct. The type for T will be inferred. You will need to declare that T is a generic type on the impl block:

struct MyStruct<T> {
    test_field: Option<T>,
    name: String,
    age: i32,
}

impl<T> MyStruct<T> {
//  ^^^
    fn new(new_age: i32, new_name: String) -> MyStruct<T> {
        MyStruct {
            test_field: None,
            age: new_age,
            name: new_name,
        }
    }
}

As DK. points out, you could choose to specify the type parameter using the turbofish syntax (::<>):

MyStruct::<T> {
//      ^^^^^
    test_field: None,
    age: new_age,
    name: new_name,
}

Modern compiler versions actually tell you this now:

  = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
  = help: or use `(...)` if you meant to specify fn arguments

I've only ever seen something like this when the types are ambiguous, which doesn't happen very often.

like image 102
Shepmaster Avatar answered Nov 07 '22 17:11

Shepmaster