如何告诉编译器我返回的枚举变量始终没有生存期?

基廷厄

下面的代码不会编译,因为编译器认为我不应该分配t1因为它是借来的,但实际上,该函数always_returns_no_lifetime将始终返回实际上没有生命周期的枚举的变体,因此可以我来修改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);

}

操场

错误是:

error[E0506]: cannot assign to `t1` because it is borrowed
  --> src/main.rs:23:5
   |
21 |     let copy = always_returns_no_lifetime(&t1);
   |                                            -- borrow of `t1` occurs here
22 |     
23 |     t1 = Types::NoLifetime(30);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `t1` occurs here
马修M.

您的函数的返回类型错误。如果保证返回值没有任何生存期,则应将其标记为此类,并且不应将其绑定到任意生存期:

fn always_returns_no_lifetime(...) -> Types<'static>;

进行此更改后,实际上您也不再需要任何输入生存期,因为它们仅对绑定输入和输出有用,从而导致以下签名:

fn always_returns_no_lifetime(some_type: &Types) -> Types<'static>;

不幸的是,这意味着clone现在已经不存在了,因为它会克隆生存期,因此实现也必须更改:

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);
}

如果保留不需要的生存期,则无法编译此示例,这是不必要的限制。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何让编译器在我的板条箱/文件中发出变量的生存期?

返回带有“ static”的类型是否会告诉编译器此值没有关联的生存期,还是会使该值变为静态?

有没有一种方法可以从Rust编译器获取淘汰的生存期参数?

返回带有自我生存期的参考

为什么Rust编译器要求我约束通用类型参数的生存期(错误E0309)?

具有生存期值的Rust函数返回类型

如何返回具有多个生存期的impl迭代器?

别名具有生存期的泛型函数?

如何使用带有生存期的类型作为io :: Error :: new的`error`参数?

如何将返回值的生存期设置为要移入的变量的生存期?

编译器建议我添加一个“静态生存期,因为参数类型的生存期可能不够长,但是我认为这不是我想要的”

这个对象生存期延长关闭是C#编译器错误吗?

为什么编译器为特征及其实现推断不同的生存期?

使用闭包返回对枚举变量内容的引用时,“无法推断适当的生存期”

如何根据编译功能标志将生存期添加到枚举

具有生存期限制的递归函数内部循环中的借入检查器错误

如何使用impl函数声明枚举生存期?

从函数返回的迭代器的生存期要求冲突

将具有生存期的借用引用强制转换为Rust中的原始指针

当使用带有生存期说明符的函数时,借入的值寿命不足

带有生存期参数的方法的函数指针类型

Rust字符串生存期和迭代器适配器(生存期编译错误)

如何设置不是函数自变量的引用的生存期?

函数内部局部变量的生存期如何延长?

具有多个生存期的迭代器

无论如何,有没有告诉编译器通过注释保留变量名?

Java编译-有没有办法告诉编译器忽略我的部分代码?

有没有办法传递对泛型函数的引用并返回与参数的生存期无关的impl特性?

循环变量生存期的C ++很奇怪