How to default forgotten fields

Hi, i am strugling with default my B struct, i comment for showing the expected default values:

const ROCK: i32 = 750;

#[derive(Debug)]
struct PrecursorA {
    alpha_u8_nodefault: u8,     
}

#[derive(Debug)]
struct A {
    precursorA: PrecursorA,
    x: u32,
}

#[derive(Default, Debug)]
struct PrecursorB {
    beta_optioni32_with_option: Option<i32>, // i want it = Some(666) if forgotten at init !
    beta_u8_with_default_zero: u8, // i want it = 0
    beta_u8_with_default_123: u8, // i want it = 123 by default !
    //beta_i32_with_ROCK_const_default: i32, // i want it to duplicate ROCK value which is global constant
}

impl PrecursorB {
    fn new(&mut self) -> Self {
        Default::default()
        //Default::default(&self.beta_u8_with_default_zero)
        //Default::default(&self.beta_u8_with_default_123=123u8)
        //Default::default(&self.beta_i32_withdefault=ROCK)
    }
}

#[derive(Debug)]
struct B {
    precursorB: PrecursorB,
    x: u32,
}

trait T {
    fn triple(&self) -> u32;
}

macro_rules! impl_T {
    (for $($t:ty),+) => {
        $(impl T for $t {
            fn triple(&self) -> u32 {
                self.x * 3
            }
        })*
    }
}

impl_T!(for A, B);

fn main() {    
    let a = A { precursorA : PrecursorA{alpha_u8_nodefault: 8}, x: 1 };
    
    let b = B { precursorB : PrecursorB{beta_u8_with_option: Some(15), beta_u8_with_default_zero: Default::default(0)}, x: 2 };    

    println!("a.x    {}", a.x);
    println!("a      {:?}", a);
    println!("b      {:?}", b);
    println!("a.triple    {}", a.triple());
}

If I am understanding your example, I think you want to implement Default for your struct: https://doc.rust-lang.org/std/default/trait.Default.html

If you don't want some struct field to have its own default value in Default implementation for struct, you have to implement Default yourself. derive won't work.

hello, i already read this page but i'm stuck

hi, can you illustrate it for one field please?

If I understand correctly, here it is (for all fields, it's not different):

const ROCK: i32 = 750;

#[derive(Debug)]
struct PrecursorB {
    beta_optioni32_with_option: Option<i32>, // i want it = Some(666) if forgotten at init !
    beta_u8_with_default_zero: u8,           // i want it = 0
    beta_u8_with_default_123: u8,            // i want it = 123 by default !
    beta_i32_with_ROCK_const_default: i32, // i want it to duplicate ROCK value which is global constant
}

impl Default for PrecursorB {
    fn default() -> Self {
        Self {
            beta_optioni32_with_option: Some(666),
            beta_u8_with_default_zero: 0,
            beta_u8_with_default_123: 123,
            beta_i32_with_ROCK_const_default: ROCK,
        }
    }
}

fn main() {
    println!("{:?}", PrecursorB::default());
}

Playground

1 Like

Sorry @laticoda I rushed the response and should've given you an example.
Thank you @Cerberuser for providing that!

thank you guys, here is my final test:
const ROCK: i32 = 750;

#[derive(Debug)]
struct PrecursorA {
    alpha_u8_nodefault: u8,     
}

#[derive(Debug)]
struct A {
    precursorA: PrecursorA,
    x: u32,
}

#[derive(Debug)]
struct PrecursorB {
    beta_i32_with_option: Option<i32>, // i want it = Some(666) if forgotten at init !
    beta_u8_with_default_zero: i32, // i want it = 0
    beta_u8_with_default_123: i32, // i want it = 123 by default !
    beta_i32_with_ROCK_const_default: i32, // i want it to duplicate ROCK value which is global constant
}

impl Default for PrecursorB {
    fn default() -> Self {
        Self {
            beta_i32_with_option: Some(666),
            beta_u8_with_default_zero: 0,
            beta_u8_with_default_123: 123,
            beta_i32_with_ROCK_const_default: ROCK,
        }
    }
}


#[derive(Debug)]
struct B {
    precursorB: PrecursorB,
    x: u32,
}

trait T {
    fn triple(&self) -> u32;
}

macro_rules! impl_T {
    (for $($t:ty),+) => {
        $(impl T for $t {
            fn triple(&self) -> u32 {
                self.x * 3
            }
        })*
    }
}

impl_T!(for A, B);

fn main() {    
    let a = A { precursorA : PrecursorA{alpha_u8_nodefault: 8}, x: 1 };    
    let b = B { precursorB : PrecursorB{beta_i32_with_option: Some(15), .. Default::default()}, x: 2 };    

    println!("a.x    {}", a.x);
    println!("a      {:?}", a);
    println!("b      {:?}", b);
    println!("a.triple    {}", a.triple());
}
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.