-2

This doesn't compile. Why not?

The compiler is happy with the set_fred() method, but not with get_fred() and get_fred_mut() which reference the same Fred(String).

fn main() {
    println!("Unable to compile enum impl methods with values");
}

enum Flintstone {
    Fred(String),
    Wilma(i32),
}

impl Flintstone {
    fn set_fred(&mut self, fred: String) {
        *self = Flintstone::Fred(fred);
    }

    // error[E0609]: no field `Fred` on type `Flintstone`
    fn get_fred(self) -> String {
        self.Fred
    }

    // error[E0609]: no field `Fred` on type `&mut Flintstone`
    fn get_fred_mut(&mut self) -> &mut String {
        &mut self.Fred
    }
}
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Koala3
  • 2,203
  • 4
  • 20
  • 15

2 Answers2

0

They are here a couple of problems.

First is the signature of this method get_fred(self) it should be get_fred(&self) look at the following example

struct Test(i32);

impl Test {
    fn new() -> Self {
        return Self(3);
    }
    
    fn get(self) -> i32 {
        return self.0;
    }
} 

fn main() {
    let t = Test::new();
    
    // Unsurprisingly it prints "The value: 3"
    println!("The value: {}", t.get());
    
    // Because as it is declared self instead of &self in get(self)
    // The ownership is take and t is now doroped
    println!("The value: {}", t.get());
}

A fuller explanation here When to use self, &self, &mut self in methods?

Next, the Enum is only in one state. In your case is Flintstone::Fred(String) or Flintstone::Wilma(i32).

So you can deal like this

fn get_fred(&self) -> String {
    match self {
        Flintstone::Fred(a) => a.clone(), //<-- Because a is an `&String`
        _ => "".to_string()
    }
}

And the mut is not make a lot of sense

fn get_fred_mut(&mut self) -> &mut String {
    match self {
        Flintstone::Fred(ref mut a) => a,
        _ => panic!("No fred")
    }
}
Zeppi
  • 1,175
  • 6
  • 11
0

This is what I came up with. The intent is to be able to store different types in an enum.

fn main() {
    println!("Making progress compiling enum impl methods with values");
}

#[allow(dead_code)]
enum Flintstone {
    Fred(FlintstoneVal),
    Wilma(FlintstoneVal),
    Pebbles(FlintstoneVal),
}

#[allow(dead_code)]
#[allow(non_camel_case_types)]
enum FlintstoneVal {
    fred(i32),
    wilma(String),
    pebbles(bool),
}

#[allow(dead_code)]
impl Flintstone {

    fn set_fred(&mut self, fred: i32) {
        *self = Flintstone::Fred(FlintstoneVal::fred(fred));
    }

    fn get_fred(&self) -> i32 {
        match self {
            Flintstone::Fred(FlintstoneVal::fred(val)) => *val,
            _ => 0_i32,    // This will never match.
        }
    }

    fn set_wilma(&mut self, wilma: String) {
        *self = Flintstone::Wilma(FlintstoneVal::wilma(wilma));
    }
}
Koala3
  • 2,203
  • 4
  • 20
  • 15