How do I get a single value from an enumerated tuple

This is my code:

#[derive(Debug)]
pub enum ResultCode {
    Success(u32, String),

    Fail(u32, String),

    Param_Not_Valid(u32, String),

    System_Execution_Error(u32, String),

    No_Data_Found(u32, String),
}

impl ResultCode {
    
    pub fn get_success() -> ResultCode {
        ResultCode::Success(200, String::from("成功"))
    }

    pub fn get_fail() -> ResultCode {
        ResultCode::Fail(500, String::from("失败"))
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn test_success() {
        let success = ResultCode::get_success();

        println!("{:?}", success);
    }
}

test_success() how to get u32 or get String

impl ResultCode {

    pub fn get_code(data: ResultCode) -> u32 {
        data.  ?????
    }

    pub fn get_code(data: ResultCode) -> String {
        data.  ?????
    }
}
if let ResultCode::Success(_code, text) = data {
    return text;
} else {
    panic!("Not a Success");
}
impl ResultCode {

    pub fn get_code(data: ResultCode) -> u32 {
        match data {
            ResultCode::Success(code, _)                    => code,
            ResultCode::Fail(code, _)                       => code,
            ResultCode::Param_Not_Valid(code, _)            => code,
            ResultCode::System_Execution_Error(code, _)     => code,
            ResultCode::No_Data_Found(code, _)              => code,
        }
    }

    pub fn get_message(data: ResultCode) -> &'static str {
        match data {
            ResultCode::Success(_, message)                    => &message,
            ResultCode::Fail(_, message)                       => &message,
            ResultCode::Param_Not_Valid(_, message)            => &message,
            ResultCode::System_Execution_Error(_, message)     => &message,
            ResultCode::No_Data_Found(_, message)              => &message,
        }
    }
    
    pub fn get_success() -> ResultCode {
        ResultCode::Success(200, String::from("成功"))
    }

    pub fn get_fail() -> ResultCode {
        ResultCode::Fail(500, String::from("失败"))
    }
}

get_message() error It looks like a static life cycle

message: String
Go to String

cannot return value referencing local variable `message`
returns a value referencing data owned by the current functionrustcE0515
result_code.rs(34, 67): `message` is borrowed here

If I return the string type, I need to make a & reference every time I use the value. I think I can return the value decorated with a & value

@alice hi alice :grinning:

The life cycle of rust is hard to understand. Who can help me emo :(

You can take in an owned value (no &) and return an owned value:

    pub fn get_message(data: ResultCode) -> String {
    //                                      ^^^^^^
        match data {
            // Note: Not &message
            ResultCode::Success(_, message)                    => message,
            ResultCode::Fail(_, message)                       => message,
            ResultCode::Param_Not_Valid(_, message)            => message,
            ResultCode::System_Execution_Error(_, message)     => message,
            ResultCode::No_Data_Found(_, message)              => message,
        }
    }

Or you can take in a borrowed value and return a borrowed value:

    pub fn get_message(data: &ResultCode) -> &str {
    //                       ^               ^
    // Note: Not &'static str
        match data {
            ResultCode::Success(_, message)                    => &message,
            ResultCode::Fail(_, message)                       => &message,
            ResultCode::Param_Not_Valid(_, message)            => &message,
            ResultCode::System_Execution_Error(_, message)     => &message,
            ResultCode::No_Data_Found(_, message)              => &message,
        }
    }

But you can't take in owned data and then return a reference to it. The owned data goes away at the end of the function (except for any owned parts you return).

1 Like

if return String, i can use String::from(message); so but i want return &str

You can only return a &str if one of the arguments to the function (or a global variable or leaked memory) owns the string data you are returning a reference to.

 pub fn get_message(data: ResultCode) -> &str {
        match data {
            ResultCode::Success(_, message)                    => &message,
            ResultCode::Fail(_, message)                       => &message,
            ResultCode::Param_Not_Valid(_, message)            => &message,
            ResultCode::System_Execution_Error(_, message)     => &message,
            ResultCode::No_Data_Found(_, message)              => &message,
        }
    }

Can I use the declaration cycle to modify the code? But it seems that this has nothing to do with the life cycle. It seems that in terms of ownership, I know a Box::new() can be used

You can't return &str in that function because there's nowhere to give ownership of the string data. Someone must own it for as long as it exists, and if you return &str, then the returned value is not the owner.

I think I can think about it again. I probably understand. Thanks @alice @quinedot @2e71828

If you only use literal strings ("..."), you can use &'static str instead of String everywhere. But then you can't do things like:

    pub fn path_failure(path: Path) -> ResultCode {
        let err = format!("file not found: {}", path.display());
        ResultCode::Fail(500, err)
    }

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.