下面的代码不会编译,因为编译器认为我不应该分配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
您的函数的返回类型错误。如果保证返回值没有任何生存期,则应将其标记为此类,并且不应将其绑定到任意生存期:
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] 删除。
我来说两句