如何在结构体中与常量值匹配一个字符串?

12
在Rust中,可以使用静态的str值与结构体中的String进行匹配吗?以下是一个最简示例:
struct SomeStruct {
    a: String,
}

fn main() {
    let s = SomeStruct {
        a: "Test".to_string(),
    };
    match s {
        SomeStruct { a: "Test" } => {
            println!("Match");
        }
    }
}

由于静态str引用无法与String成员进行匹配,因此这段代码无法编译。不使用解构a并在匹配语句中添加嵌套的if语句,是否可以使其正常工作?

2个回答

13

目前还无法使用单个模式完成此操作,尽管在某些时候可能会变得可能。现在,最简单的方法可能是用一个模式和匹配守卫替换模式,像这样:

match s {
    SomeStruct { ref a } if a == "Test" => {
        println!("Match");
    }
}

2

稍微有些超前思考,您可以创建一个并行类型,它具有&str而不是String,并添加一种方法来在它们之间进行转换:

struct SomeStruct {
    a: String,
}

impl SomeStruct {
    fn as_ref(&self) -> SomeStructRef {
        SomeStructRef { a: &self.a }
    }
}

struct SomeStructRef<'a> {
    a: &'a str,
}

fn main() {
    let s = SomeStruct {
        a: "Test".to_string(),
    };
    match s.as_ref() {
        SomeStructRef { a: "Test" } => {
            println!("Match");
        }
        _ => panic!(),
    }
}

您可以创建一个常量来匹配您想要匹配的值:
#[derive(PartialEq, Eq)]
struct SomeStructRef<'a> {
    a: &'a str,
}

const TEST_STRUCT: SomeStructRef = SomeStructRef { a: "Test" };

fn main() {
    let s = SomeStruct {
        a: "Test".to_string(),
    };
    match s.as_ref() {
        TEST_STRUCT => {
            println!("Match");
        }
        _ => panic!(),
    }
}

这里没有具体针对结构体的内容,相同的概念也适用于枚举类型:
enum SomeEnum {
    One(String),
    Two(String),
}

impl SomeEnum {
    fn as_ref(&self) -> SomeEnumRef {
        match self {
            SomeEnum::One(v) => SomeEnumRef::One(v),
            SomeEnum::Two(v) => SomeEnumRef::Two(v),
        }
    }
}

enum SomeEnumRef<'a> {
    One(&'a str),
    Two(&'a str),
}

fn main() {
    let s = SomeEnum::Two("Test".to_string());
    match s.as_ref() {
        SomeEnumRef::Two("Test") => {
            println!("Match");
        }
        _ => panic!(),
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接