Initializing a generic types field in a struct

Way back last August I started a thread that discussed using generic types in a set of nested structs. We had some good discussions, but, honestly, I never did succeed at applying the suggestions from the people here on this forum. I found a different workaround, but the truth is I do need to master the use of enums and generics. Now I find myself once again needing that skill. So, I pulled up an example (from the thread linked above) and have been (unsuccessfully) attempting to modify it to fit what I need to do. And, of course, I'm stuck and need help. Here's what I have so far:

#[derive(Debug)]
pub struct VarPrmtrs {
    is_string: bool,
    is_num: bool,
    is_int: bool,
    is_signed: bool,
    num_dcml_places: u32,
    num_comma_frmttd: bool,
    is_from_list: bool,
    data_fromlist: String,
}


impl VarPrmtrs {
    pub fn new() -> VarPrmtrs {
        Self {
            is_string: false,
            is_num: true, 
            is_int: true,
            is_signed: true,
            num_dcml_places: 0,
            num_comma_frmttd: false,
            is_from_list: false,
            data_fromlist: "".to_string(),         
        }
    }
} // ~~~~~ End VarPrmtrs impl ~~~~~

#[derive(Debug)]
pub enum TypeWrapper {
    Alphanum(<String>),
    Unsigned(<u64>),
    Integer(<i64>),
    Floating(<f64>),
}

#[derive(Debug)]
pub struct VarData {
    title: String,
    params: VarPrmtrs,
    content: TypeWrapper,
}

impl VarData {
    pub fn new() -> VarData {
        Self {
            title: "new_variable".to_string(),
            params: VarPrmtrs::new(),
            content<TypeWrapper>: 
        }
    }
} 

Nothing works, my syntax is all wrong (I'm sure), but this is where I'm at. The problem shows up when I try, in the impl VarData block, to initialize the content field for the VarData struct because it really needs to have a generic type based on user input. I added the TypeWrapper enum in an attempt to get this working and, of course, it doesn't work.

So, suggestions?

Right now you don't have any generic structs. It's not clear from your syntax error places what you actually want to achieve. Should each VarData store one value of one of the choices of type? Many of the same type? Where should it get these actual values from? Answering these questions will help determine what the correct solution in.

So, maybe this?

pub struct VarData <TypeWrapper>  {
...
            content<TypeWrapper>: 
        }

Only the content field needs to be generic as it will need to contain data from any of the String, i64, u64, or f64 types, depending on user choice.

This is an application targeted at teachers that will be used to generate questions for use in worksheets, tests, and quizzes using dynamic content contained in the content field of the VarData struct.

One value of one type. Yet-to-be-written functions will generate that data and insert it into that field.

You already have an enum representing the type the user choose (which is TypeWrapper) and that's the correct way to model a value that can have different types at runtime. I'm not sure why you're trying to bring generics in here. Generics allow you to create types that contain a type chosen at compile time, but based on your description that isn't relevant to the problem at hand.

I'm also not sure why you put angle brackets around the types in TypeWrapper. It looks like you probably don't need those at all.

You know, I thought I tried just parentheses before, but I guess not. Here's what it looks like now:

pub enum TypeWrapper {
    Alphanum(String),
    Unsigned(u64),
    Integer(i64),
    Floating(f64),
}

You're right that with this enum I shouldn't need generics, but I still haven't found the right way to initialize the content field in the VarData struct. Here's what it looks like right now, and the compiler doesn't like it.

impl VarData<TypeWrapper> {
    pub fn new() -> VarData<TypeWrapper> {
        Self {
            title: "new_variable".to_string(),
            params: VarPrmtrs::new(),
            content: TypeWrapper,
        }
    }
}

So, how do I initialize that field properly?

First, you're still using generics where they don't make sense. Remove the <TypeWrapper> — not only is it not needed, you're also hiding the concrete type you already created, enum TypeWrapper, with a type variable also named TypeWrapper.

impl VarData {
    pub fn new() -> VarData {

Now, the next problem is initializing the content field. Just like any other field, it needs an actual value. Do you want it to be a placeholder like your other fields? Then do that, like:

        Self {
            title: "new_variable".to_string(),
            params: VarPrmtrs::new(),
            content: TypeWrapper::Alphanum(String::new()),
        }

Or do you want the caller to supply a value of a specific type? Then add a parameter to new():

impl VarData {
    pub fn new(content: TypeWrapper) -> VarData {
        Self {
            title: "new_variable".to_string(),
            params: VarPrmtrs::new(),
            content: content,
        }
    }
}

Either way, you can't not pick a value for content to have.

Or if the value isoptional, the field should be of type Option<TypeWrapper>.[1]


  1. Or less idiomatically, have your own None-like variant. ↩︎

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.