gpt4 book ai didi

vector - 为什么 Vec.sort() 似乎需要静态生命周期?

转载 作者:行者123 更新时间:2023-12-03 11:25:33 25 4
gpt4 key购买 nike

这是我遇到的问题的一个大大简化的例子,但是给出了一个实现 Ordtrait Thing 和一个 struct Object 实现了 Thing,我有以下结构:

pub struct MyStruct<'a> {
my_things: HashMap<i32, Vec<Box<dyn Thing + 'a>>>
}

impl<'a> MyStruct<'a> {
pub fn new() -> MyStruct<'a> {
MyStruct {
my_things: HashMap::new()
}
}

pub fn add_object(&mut self, key: i32, obj: Object) {
if !self.my_things.contains_key(&key) {
self.my_things.insert(key, Vec::new());
}

let new_thing: Box<dyn Thing> = Box::new(obj);
let things = self.my_things.get_mut(&key).unwrap();

things.push(new_thing);
things.sort();
}
}

它本质上需要一个键和一个对象,并使用给定的键将对象添加到VecHashMap 中。我知道这不是执行此操作的最佳方法,但我想让它更简单以供说明。

编译器在调用 things.sort() 时出现以下错误:

error[E0308]: mismatched types
--> src/main.rs:58:16
|
58 | things.sort();
| ^^^^ lifetime mismatch
|
= note: expected trait `Ord`
found trait `Ord`
note: the lifetime `'a` as defined on the impl at 42:6...
--> src/main.rs:42:6
|
42 | impl<'a> MyStruct<'a> {
| ^^
= note: ...does not necessarily outlive the static lifetime

Playground link

如果我在此示例中删除所有 'a 生命周期,代码将编译。但对于我的实际用例,我需要允许非静态生命周期。

有人能解释一下这是怎么回事吗? sort() 是否真的要求 Vec 包含具有静态生命周期的项目?如果是,为什么?

是否有好的解决方法?

最佳答案

您只为 dyn Thing + 'static 实现了 Ord。如果您没有明确指定任何其他生命周期界限,则会推断出 'static 生命周期界限。要为非 'static dyn Thing 实现 Ord,您需要引入并使用通用生命周期参数,例如'a,在您的实现中。更新编译示例:

use std::collections::HashMap;
use std::cmp;

pub trait Thing {
fn priority(&self) -> i32;
}

impl<'a> PartialEq for dyn Thing + 'a { // 'a added here
fn eq(&self, other: &Self) -> bool {
self.priority() == other.priority()
}
}

impl<'a> PartialOrd for dyn Thing + 'a { // 'a added here
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.priority().partial_cmp(&other.priority())
}
}

impl<'a> Eq for dyn Thing + 'a {} // 'a added here

impl<'a> Ord for dyn Thing + 'a { // 'a added here
fn cmp(&self, other: &Self) -> cmp::Ordering{
self.priority().cmp(&other.priority())
}
}

pub struct Object {
priority: i32,
}

impl Thing for Object {
fn priority(&self) -> i32 {
self.priority
}
}

pub struct MyStruct<'a> {
my_things: HashMap<i32, Vec<Box<dyn Thing + 'a>>>
}

impl<'a> MyStruct<'a> {
pub fn new() -> MyStruct<'a> {
MyStruct {
my_things: HashMap::new()
}
}

pub fn add_object(&mut self, key: i32, obj: Object) {
if !self.my_things.contains_key(&key) {
self.my_things.insert(key, Vec::new());
}

let new_thing: Box<dyn Thing> = Box::new(obj);
let things = self.my_things.get_mut(&key).unwrap();

things.push(new_thing);
things.sort();
}
}

fn main() {
let _test = MyStruct::new();
}

playground


来自 the Default Trait Object Lifetimes section of the Lifetime Elision chapter of the Rust Reference (强调我的):

If the trait object is used as a type argument of a generic type then the containing type is first used to try to infer a bound.

  • If there is a unique bound from the containing type then that is the default
  • If there is more than one bound from the containing type then an explicit bound must be specified

If neither of those rules apply, then the bounds on the trait are used:

  • If the trait is defined with a single lifetime bound then that bound is used.
  • If 'static is used for any lifetime bound then 'static is used.
  • If the trait has no lifetime bounds, then the lifetime is inferred in expressions and is 'static outside of expressions.

关于vector - 为什么 Vec.sort() 似乎需要静态生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66082476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com