Rust 我怎样才能退回a&;方法impl中枚举中字符串的str?

Rust 我怎样才能退回a&;方法impl中枚举中字符串的str?,rust,borrow-checker,Rust,Borrow Checker,我想返回城市/城镇/村庄的名称,作为对str的引用。我可以在实现中指定生存期,但也为枚举指定它会导致错误,因为它没有声明引用 enum CityType { City { name: String /* ... */ }, Town { name: String /* ... */ }, Village { name: String /* ... */ }, } impl CityType { fn name(self) -> &str {

我想返回城市/城镇/村庄的名称,作为对
str
的引用。我可以在实现中指定生存期,但也为枚举指定它会导致错误,因为它没有声明引用

enum CityType {
    City { name: String /* ... */ },
    Town { name: String /* ... */ },
    Village { name: String /* ... */ },
}

impl CityType {
    fn name(self) -> &str {
        match self {
            CityType::City { name } => &name,
            CityType::Town { name, .. } => &name,
            CityType::Village { name } => &name,
        }
    }
}

如果您只想返回一个城市名称,而不想因消费而丢失对象,则应按以下方式编写:

enum CityType {
    City { name: String },
    Town { name: String },
    Village { name: String },
}

impl CityType {
    fn name(&self) -> &str {
        match *self {
            CityType::City { ref name } => name,
            CityType::Town { ref name, .. } => name,
            CityType::Village { ref name } => name,
        }
    }
}

fn main() {
    let city = CityType::City { name: "NY".to_owned() };
    println!("Name of the city: {}", city.name());
}
fn name<'a>(&'a self) -> &'a str {
说明:

  • 首先,方法的签名指定使用对象:

    fn name(self) -> &str {
    
    调用此类方法后,您将无法再使用该实例。如果要读取字符串,应接受引用:

    fn name(&self) -> &str {
    
    这导致了另一个问题

  • match
    应该在不移动对象的情况下工作,因此这里是
    *

    match *self {
    
  • 您不应该从枚举的数据中移出,因此
    ref
    关键字有帮助

    CityType::City { ref name } => name,
    
    这个关键字表示我们必须使用模式匹配来引用值

  • main
    中,您传递了一个
    &str
    ,但枚举中的项是
    字符串,因此这会导致不兼容类型错误。通过对字符串引用调用
    .to_owned()
    方法,可以从中创建一个新的
    string
    对象:

    let city = CityType::City { name: "NY".to_owned() };
    
  • 请发表评论:

    问题更一般:如何将ref返回到一个没有生存期说明符的字符串,因为它的生存期与枚举的生存期一样长

    在Rust中,你不可能拥有一个没有生命的参考。从未。在某些情况下,编译器可以为您推断生存期,但也有一些情况下,编译器会错误地推断生存期或推断出与您预期不符的生存期。在这种情况下,例如:

    fn name(&self) -> &str {
    
    生命周期,编译器将其视为以下内容:

    enum CityType {
        City { name: String },
        Town { name: String },
        Village { name: String },
    }
    
    impl CityType {
        fn name(&self) -> &str {
            match *self {
                CityType::City { ref name } => name,
                CityType::Town { ref name, .. } => name,
                CityType::Village { ref name } => name,
            }
        }
    }
    
    fn main() {
        let city = CityType::City { name: "NY".to_owned() };
        println!("Name of the city: {}", city.name());
    }
    
    fn name<'a>(&'a self) -> &'a str {
    
    fn name&'a str{
    

    您的引用绑定到同一个生存期,并且可以使用它们。

    您希望
    name
    method做什么?它有多个问题,答案可能取决于您的意图。@VictorPolevoy在本例中只需将ref返回到字符串。问题更一般:如何将ref返回到没有生存期说明符的字符串因为它的寿命与枚举的寿命一样长。您需要(重新)阅读锈书中的章节。
    name(self)
    拥有枚举的所有权,并且在函数返回时取消分配枚举。您无法返回对取消分配枚举的引用。感谢您的解释。这正是我的使用案例。