reference - 在 Vec 中混合引用的生命周期

标签 reference rust lifetime

我正在尝试生成 Vec<&'b Color>来自 Vec<&'a Color> :

impl <'a> Canvas<'a> {
    pub fn modify<'b>(&self, update: Update) -> Canvas<'b> {
        let x  = update.x;
        let y  = update.y;
        let colors: Vec<&'b Color> = self.colors.iter().enumerate().map(move |(index, color)| {
                if index == self.width * y + x { update.color } else { color }
            })
            .collect();
        Canvas { width: self.width, height: self.height, colors: colors }
    }
}

但是,我收到以下错误:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/canvas.rs:51:50
   |
51 |         let colors: Vec<&'b Color> = self.colors.iter().enumerate().map(move |(index, color)| {
   |                                                  ^^^^

如何创建 Vec多种颜色,只有一种颜色具有使用生命周期 'a ,以及剩余的生命周期'b

如果需要,相关定义如下:

#[derive(Debug, PartialEq, Eq)]
pub enum Color {
    White,
    Red,
    Blue,
    Green,
    Purple,
    Orange
}

pub struct Update<'a> {
    color: &'a Color,
    x: usize,
    y: usize
}

pub struct Canvas<'a> {
    width: usize,
    height: usize,
    colors: Vec<&'a Color>
}

最佳答案

How can I create a Vec of colors, all but one with lifetime 'a, and the remaining with lifetime 'b?

不能。生命周期是泛型,就像拥有“一个 Vec<T> 没有意义一样,T 中除了一个是 String 类型,其余 Tbool 类型”,它对生命周期这样做没有意义。

你可以做的是统一生命周期:

impl<'a> Canvas<'a> {
    pub fn modify(&self, update: Update<'a>) -> Canvas<'a> {
        let x = update.x;
        let y = update.y;
        let colors = self.colors
            .iter()
            .enumerate()
            .map(move |(index, color)| if index == self.width * y + x {
                     update.color
                 } else {
                     color
                 })
            .collect();
        Canvas {
            width: self.width,
            height: self.height,
            colors: colors,
        }
    }
}

在这里,我们说 update.color生命周期和包含的引用的生命周期有一个交集,这就是结果的生命周期。


对于一组固定类型的异构集合,另一种常见的解决方案是引入一个枚举,每个枚举都有变体:

pub enum Thing<'a, 'b>  {
    A(&'a Color),
    B(&'b Color),
}

impl<'a> Canvas<'a> {
    pub fn modify<'b>(&self, update: Update<'b>) -> Vec<Thing<'a, 'b>> {
        let x = update.x;
        let y = update.y;
        self.colors
            .iter()
            .enumerate()
            .map(move |(index, color)| if index == self.width * y + x {
                     Thing::B(update.color)
                 } else {
                     Thing::A(color)
                 })
            .collect()
    }
}

关于reference - 在 Vec 中混合引用的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43359159/

相关文章:

reference - Tableau 表格上的引用线

functional-programming - 如何声明遵循函数类型的常规(非闭包)函数?

rust - 如何在Rust中为返回的元组设置静态生存期?

c++ - 临时绑定(bind)到引用是否需要 C++ 中的复制构造函数?

c# - 我的 C# 程序集还是我的代码?

rust - 如何使用和替换 &mut ref 中的值

php - 如何设置 session 的生命周期

return - 有效地获取借用引用的所有权以从函数返回

c++ - 从搜索 STL vector 的函数返回引用

rust - 无法使用 std::process::Command - 没有这样的文件或目录