为包含 Cow<'a, str> 的枚举实现 ToOwned ('a -> 'static) 会导致未满足生命周期要求

m0m*_*eni 3 rust

语境

游乐场链接:https://play.rust-lang.org/?version= stable&mode=debug&edition=2021&gist=de1286b8bce0dfb840a5fc0b50df25ad

我正在阅读另一篇 SO 文章,其中说您可以将包含 a 的结构转换Cow为具有'static生命周期。根据该帖子,我尝试了以下操作:

use std::borrow::Cow;

enum S<'a> {
    A(Cow<'a, str>),
    B(i32)
}

impl ToOwned for S<'_> {
    type Owned = S<'static>;
    
    fn to_owned(&self) -> Self::Owned {
        match *self {
            S::A(s) => S::A(Cow::Owned(s.clone().into_owned())),
            S::B(i) => S::B(i)
        }
    }
}

fn main() {
    let s = S::A("a".into());
    let s = s.to_owned();
}
Run Code Online (Sandbox Code Playgroud)

并得到以下错误

error: incompatible lifetime on type
   --> src/main.rs:9:18
    |
9   |     type Owned = S<'static>;
    |                  ^^^^^^^^^^
    |
note: because this has an unmet lifetime requirement
note: the lifetime `'_` as defined here...
   --> src/main.rs:8:20
    |
8   | impl ToOwned for S<'_> {
    |                    ^^
note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
Run Code Online (Sandbox Code Playgroud)

问题

  • 如果我将其转换Cow为拥有的版本,生命周期究竟如何发挥作用?
  • 让它发挥作用的正确方法是什么?

Cha*_*man 6

TL;DR:您无法ToOwned为此实施;使用固有的方法。


ToOwned::Owned有一个界限:

type Owned: Borrow<Self>;
Run Code Online (Sandbox Code Playgroud)

所以我们需要为任何S<'static>impl 。Borrow<S<'a>>'a

...除了这个 impl 不能写:

error[E0119]: conflicting implementations of trait `std::borrow::Borrow<S<'static>>` for type `S<'static>`
  --> src/main.rs:19:1
   |
19 | impl<'a> Borrow<S<'a>> for S<'static> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> Borrow<T> for T
             where T: ?Sized;
Run Code Online (Sandbox Code Playgroud)

...因为它与 的Borrow<T> for T总体实现相冲突。'a'static

没有这个 impl 的编译器错误是由于编译器发现存在一个impl<'a> Borrow<S<'a>> for S<'static>(上述一揽子实现),只是它约束了'a: 'static. 因此编译器尝试证明'a: 'static,但失败了。这是编译器过于智能的一个示例,导致出现令人困惑的错误消息。