我对下面的代码有问题...

use std::collections::BTreeSet;
use maybe_owned::MaybeOwned;

struct Thing<'a, T> {
    set: BTreeSet<MaybeOwned<'a, T>>
}

impl<'a, T: Ord> Thing<'a, T> {
    fn take(&mut self, x: T){
        let y = self.set.take(&MaybeOwned::Borrowed(&x));
    }
}

给出编译器错误

error[E0597]: `x` does not live long enough
  --> src/main.rs:10:53
   |
8  | impl<'a, T: Ord> Thing<'a, T> {
   |      -- lifetime `'a` defined here
9  |     fn take(&mut self, x: T){
10 |         let y = self.set.take(&MaybeOwned::Borrowed(&x));
   |                 ------------------------------------^^--
   |                 |                                   |
   |                 |                                   borrowed value does not live long enough
   |                 argument requires that `x` is borrowed for `'a`
11 |     }
   |     - `x` dropped here while still borrowed

然而,此时x显然没有被borrow ,因为Maybeown已超出范围,因此所附的borrow 已超出范围.

我怎样才能告诉rust编译器这没问题?

推荐答案

问题是,虽然临时MaybeOwned人不会活那么久,但这并不重要,因为它隐含着MaybeOwned<'a, T>.这意味着x的生命周期 必须至少与'a的生命周期 相同,但事实并非如此.临时MaybeOwned的生命周期 不会那么长,这一事实与借债人无关.

BTreeSet::take()的第二个参数是&Q,其中集合本身的T实现Borrow<Q>.MaybeOwned<'a, T>没有实现Borrow<MaybeOwned<'b, T>>,其中'b: 'a,但所有T&T都实现Borrow<T>,这多亏了一个整体实现,所以给定一个&MaybeOwned<'_, T>类型的参数,满足T: Borrow<Q>约束的唯一生存期是&MaybeOwned<'a, T>——因此,临时MaybeOwned的生存期参数被推断为'a.这是满足trait 界限的唯一方法.

谢天谢地,这些都无关紧要,因为MaybeOwned<'_, T>实现了Borrow<T>,这意味着你可以只提供&T:

let y = self.set.take(&x);

Rust相关问答推荐

如何从polars DataFrame中获取一个列作为Option String?<>

如何获取Serde struct 的默认实例

除了调用`waker.wake()`之外,我如何才能确保future 将再次被轮询?

铁 rust 中的泛型:不能将`<;T作为添加>;::Output`除以`{Float}`

用于判断整数块是否连续的SIMD算法.

将Vec<;U8&>转换为Vec<;{Float}&>

在铁 rust 中,如何一次只引用几件事中的一件?

Rust移动/复制涉及实际复制时进行检测

为什么将易错函数的泛型结果作为泛型参数传递 infer ()?不应该是暧昧的吗?

如何重命名 clap_derive 中的子命令占位符?

如何为整数切片定义一个带有额外函数的特性别名?

go 重并堆积MPSC通道消息

在发布中包含 Rust DLL

使用自定义 struct 收集 Vec

仅在运行测试时生成调试输出

将 `&T` 转换为新类型 `&N`

如何在 Rust 中编写涉及异步的重试函数

如何为返回正确类型的枚举实现 get 方法?

Rust 内联 asm 中的向量寄存器:不能将 `Simd` 类型的值用于内联汇编

在传输不可复制的值时实现就地枚举修改