代码之家  ›  专栏  ›  技术社区  ›  K. Biermann

借来的价值对于'AsRef'结果来说寿命不够长,即使它的'self'寿命足够长

  •  2
  • K. Biermann  · 技术社区  · 6 年前

    我有一个结构,它将一些功能包装在一个切片上:

    use std::fmt::Debug;
    
    struct SliceWrapper<'a, T: Debug + Copy + 'a> {
        slice: &'a [T],
        pos: usize,
    }
    

    我想实施 From 支持的每个元素的特性 AsRef<T: Debug + Copy + 'a> 这样地:

    impl<'a, T: Debug + Copy + 'a, R: AsRef<[T]> + 'a> From<R> for SliceWrapper<'a, T> {
        fn from(slice: R) -> Self {
            Self {
                slice: slice.as_ref(),
                pos: 0,
            }
        }
    }
    

    我得到一个错误:

    error[E0597]: `slice` does not live long enough
      --> src/lib.rs:11:20
       |
    11 |             slice: slice.as_ref(),
       |                    ^^^^^ borrowed value does not live long enough
    ...
    14 |     }
       |     - borrowed value only lives until here
       |
    note: borrowed value must be valid for the lifetime 'a as defined on the impl at 8:6...
      --> src/lib.rs:8:6
       |
    8  | impl<'a, T: Debug + Copy + 'a, R: AsRef<[T]> + 'a> From<R> for SliceWrapper<'a, T> {
       |      ^^
    

    R ( slice )我必须活得和我父亲一样长 SliceWrapper 据我所知, AsRef<_> self ( )...

    2 回复  |  直到 6 年前
        1
  •  3
  •   Shepmaster Tim Diekmann    6 年前

    夜间的完整错误消息非常清楚地说明了这里发生了什么。你动 slice 进入功能 from() ,然后使用 as_ref() ,然后在作用域的末尾将其删除:

    8  | impl<'a, T: Debug + Copy + 'a, R: AsRef<[T]> + 'a> From<R> for SliceWrapper<'a, T> {
       |      -- lifetime `'a` defined here
    9  |     fn from(slice: R) -> Self {
    10 |         Self{ slice: slice.as_ref(), pos: 0 }
       |                      ^^^^^---------
       |                      |
       |                      borrowed value does not live long enough
       |                      argument requires that `slice` is borrowed for `'a`
    11 |     }
       |     - `slice` dropped here while still borrowed
    

    你正在尝试创建一个终生有效的借阅 'a ,但你借来的主人, ,活得不够长。

    这个 From trait似乎不适合这个用例。这种特性的想法是将某些数据的所有权转移到一种新类型,但是 SliceWrapper R

        2
  •  1
  •   bluss    6 年前

    您可以将转换限制为引用参数,然后您就有了一个很好的方法来表示从输入引用中获取的生命周期所需的借用:

    impl<'a, T, R> From<&'a R> for SliceWrapper<'a, T>
    where
        T: Debug + Copy + 'a,
        R: AsRef<[T]>
    {
        fn from(slice: &'a R) -> Self {
            Self {
                slice: slice.as_ref(),
                pos: 0,
            }
        }
    }
    

    您有AsRef提供给您: &'x self -> &'x [T] 无论如何 'x 然后输入一个 &'a R 这样你就可以得到一个 &'a [T] 出来

    参考咨询 From impl<'a> From<&'a str> for Cow<'a, str>