Enums 如何告诉编译器枚举I的变量';我回来总是没有生命?

Enums 如何告诉编译器枚举I的变量';我回来总是没有生命?,enums,rust,borrow-checker,Enums,Rust,Borrow Checker,下面的代码不会编译,因为编译器认为我不应该分配给t1,因为它是借用的,但实际上函数总是返回\u no\u life总是返回枚举的一个变量,实际上没有生存期,所以我可以修改t1。如何让编译器理解这一点,或者如何重新组织代码以避免发生此错误 #[derive(Clone)] enum Types<'a> { NoLifetime(i32), AlsoNoLifetime(i32), AlsoAlsoNoLifetime(i32), HasLifetime(

下面的代码不会编译,因为编译器认为我不应该分配给
t1
,因为它是借用的,但实际上函数
总是返回\u no\u life
总是返回枚举的一个变量,实际上没有生存期,所以我可以修改
t1
。如何让编译器理解这一点,或者如何重新组织代码以避免发生此错误

#[derive(Clone)]
enum Types<'a> {
    NoLifetime(i32),
    AlsoNoLifetime(i32),
    AlsoAlsoNoLifetime(i32),
    HasLifetime(&'a str)
}

fn always_returns_no_lifetime<'a>(some_type: &'a Types) -> Types<'a> {
    match *some_type {
        Types::HasLifetime(text) => panic!("I only return the type that has no lifetime"),
        _ => some_type.clone()
    }
}


fn main() {
    let mut t1 = Types::NoLifetime(20);

    let copy = always_returns_no_lifetime(&t1);

    t1 = Types::NoLifetime(30);

}

不要对引用应用
'a
生存期参数,而是将其应用于
类型
,就像您对返回类型所做的那样。对引用调用
.clone()
时,引用的生存期并不重要

fn always_returns_no_lifetime<'a>(some_type: &Types<'a>) -> Types<'a> {
    match *some_type {
        Types::HasLifetime(text) => panic!("I only return the type that has no lifetime"),
        _ => some_type.clone()
    }
}

fn always\u returns\u no\u life)->Types函数的返回类型是错误的。如果保证返回值没有任何生存期,则应将其标记为生存期,而不是绑定到任意生存期:

fn always_returns_no_lifetime(...) -> Types<'static>;
此实现的好处可以在以下示例中演示:

fn tie<'a>(text: &'a str) -> Types<'a> {
    if text[0] == 'a' {
        Types::HasLifetime(text)
    } else {
        Types::NoLifetime(0)
    }
}

fn main() {
    let no_lifetime = {
        let string = String::from("Hello, world");
        let has_lifetime = tie(&*string);
        always_returns_no_lifetime(&has_lifetime)
    };

    //  Requires deriving Debug, all structs really should...
    println!("{:?}", no_lifetime);
}

fn tie types感谢您的回答,但我不太明白您在第二个示例中想展示什么。我知道你对底部的作用域做了什么,但是tie函数应该显示什么?@Keatinge:
tie
函数正在创建
类型
fn always_returns_no_lifetime(some_type: &Types) -> Types<'static> {
    match *some_type {
        Types::HasLifetime(_)
            => panic!("I only return values that have no lifetime"),
        Types::NoLifetime(i) => Types::NoLifetime(i),
        Types::AlsoNoLifetime(i) => Types::AlsoNoLifetime(i),
        Types::AlsoAlsoNoLifetime(i) => Types::AlsoAlsoNoLifetime(i),
    }
}
fn tie<'a>(text: &'a str) -> Types<'a> {
    if text[0] == 'a' {
        Types::HasLifetime(text)
    } else {
        Types::NoLifetime(0)
    }
}

fn main() {
    let no_lifetime = {
        let string = String::from("Hello, world");
        let has_lifetime = tie(&*string);
        always_returns_no_lifetime(&has_lifetime)
    };

    //  Requires deriving Debug, all structs really should...
    println!("{:?}", no_lifetime);
}