rust 为什么我应该实施“为&OpaqueHolder实施编码器”?

6l7fqoea  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(175)

如果Yimpl X&Timpl<T: X> X,为什么&Y还需要impl X?为什么只有在元组中使用它时才能看到这个?我遗漏了什么?

pub struct OpaqueHolder(str);

impl OpaqueHolder {
    fn from_borrowed(s: &str) -> &Self {
        unsafe { std::mem::transmute(s) }
    }

    fn as_str(&self) -> &str {
        &self.0
    }
}

fn make_opaque() -> &'static OpaqueHolder {
    &OpaqueHolder::from_borrowed("OpaqueHolder")
}

trait Encoder {
    fn as_encoded_string(&self) -> String;

    fn encode(&self) -> String {
        self.as_encoded_string()
    }
}

impl Encoder for OpaqueHolder {
    fn as_encoded_string(&self) -> String {
        return self.as_str().to_string()
    }
}

impl<T: Encoder> Encoder for &T {
    fn as_encoded_string(&self) -> String {
        (&**self).as_encoded_string()
    }
}

// THIS SHOULDNT BE NECESSARY< BUT FOR SOME REASON IS... WHY?
impl Encoder for &OpaqueHolder {
    fn as_encoded_string(&self) -> String {
        return self.as_str().to_string()
    }
}

impl<A: Encoder, B: Encoder> Encoder for (A, B) {
    fn as_encoded_string(&self) -> String {
        [
            self.0.as_encoded_string(),
            self.1.as_encoded_string(),
        ].concat()
    }
}

fn main() {
    // this works w/o the specific &OpaqueHolder
    println!("{:}", make_opaque().encode());
    // only shows up on the tuple
    println!("{:}", (make_opaque(), make_opaque()).encode());
}
guz6ccqo

guz6ccqo1#

这里有两件事:

  • OpaqueHolder是一个 *unsized类型 *,因为它只 Package str,这是一个unsized类型。str表示一些utf8编码的字节序列,但是该序列可以是任何长度。
  • 任何泛型型别参数(例如impl<T: Encoder> Encoder for &T)都有隐含的T: Sized条件约束。Sized是编译器在编译时期已知大小的型别上自动实作的标记特质。

所以你在&T上的泛型实现对&OpaqueHolder不起作用,因为OpaqueHolder不是Sized
若要修正这个问题,您可以使用?Sized来放松隐含的Sized界限:

impl<T: Encoder + ?Sized> Encoder for &T {
             // ^^^^^^^^
    fn as_encoded_string(&self) -> String {
        (&**self).as_encoded_string()
    }
}

现在,它将在不需要额外实现(playground)的情况下工作。

相关问题