我想返回城市/城镇/村庄的名称作为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(self) -> &str {
调用此类方法后,您将无法再使用该实例。如果要读取字符串,则应接受引用:
fn name(&self) -> &str {
这导致另一个问题match
应该在不移动物体的情况下工作,所以这里是*
:
match *self {
ref
关键字有帮助
CityType::City { ref name } => name,
这个关键字说我们必须使用模式匹配和值的引用。main
你传递&str
,但你的枚举中的项目是String
,所以这导致不兼容的类型错误。通过在字符串引用上调用.to_owned()
方法,您可以从中创建一个新的String
对象:
let city = CityType::City { name: "NY".to_owned() };
对于你的评论:
问题更为笼统:如何将ref返回到一个没有生命周期说明符的String,因为它只要枚举就行。
在Rust中,你没有一生没有参考。决不。在某些情况下,编译器可以为您推断出生命周期,但也有一些情况,它会错误地执行或不符合您的预期。在这种情况下,例如:
fn name(&self) -> &str {
有生命周期,编译器将其视为以下内容:
fn name<'a>(&'a self) -> &'a str {
您的引用必须使用相同的生命周期并且可以使用它们。