如果Y
有impl X
,&T
有impl<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());
}
1条答案
按热度按时间guz6ccqo1#
这里有两件事:
OpaqueHolder
是一个 *unsized类型 *,因为它只 Packagestr
,这是一个unsized类型。str
表示一些utf8编码的字节序列,但是该序列可以是任何长度。impl<T: Encoder> Encoder for &T
)都有隐含的T: Sized
条件约束。Sized
是编译器在编译时期已知大小的型别上自动实作的标记特质。所以你在
&T
上的泛型实现对&OpaqueHolder
不起作用,因为OpaqueHolder
不是Sized
。若要修正这个问题,您可以使用
?Sized
来放松隐含的Sized
界限:现在,它将在不需要额外实现(playground)的情况下工作。