在创建存储DST的结构(例如,原始切片)时,我可以使用常规#[derive(Eq, PartialEq, Ord, PartialOrd)]
工具在我的类型上获得此特征的实现:
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct A([u8]);
Run Code Online (Sandbox Code Playgroud)
但是,如果我手动实现它们,那么编译器会抱怨我的类型没有实现Sized
:
struct A([u8]);
impl AsRef<[u8]> for A {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl<S: AsRef<[u8]>> PartialEq<S> for A {
fn eq(&self, other: &S) -> bool {
self.0.eq(other.as_ref())
}
}
impl Eq for A { }
impl<S: AsRef<[u8]>> PartialOrd<S> for A {
fn partial_cmp(&self, other: &S) -> Option<Ordering> {
let slice: &[u8] = &self.0;
slice.partial_cmp(other.as_ref())
}
}
impl Ord for A {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(&other).unwrap()
}
}
Run Code Online (Sandbox Code Playgroud)
编译结果:
rustc 1.12.0 (3191fbae9 2016-09-23)
error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
--> <anon>:20:6
|
20 | impl Eq for A { }
| ^^
|
= note: `[u8]` does not have a constant size known at compile-time
= note: required because it appears within the type `A`
= note: required because of the requirements on the impl of `std::cmp::PartialEq` for `A`
= note: required by `std::cmp::Eq`
error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
--> <anon>:29:6
|
29 | impl Ord for A {
| ^^^
|
= note: `[u8]` does not have a constant size known at compile-time
= note: required because it appears within the type `A`
= note: required because of the requirements on the impl of `std::cmp::PartialOrd` for `A`
= note: required by `std::cmp::Ord`
Run Code Online (Sandbox Code Playgroud)
如果我创建该类型的变体确实具有固定大小(例如,通过把它变成一个固定大小的阵列),那么我可以手动实现性状没有问题.
struct B([u8; 5]);
impl AsRef<[u8]> for B {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl<S: AsRef<[u8]>> PartialEq<S> for B {
fn eq(&self, other: &S) -> bool {
self.0.eq(other.as_ref())
}
}
impl Eq for B { }
impl<S: AsRef<[u8]>> PartialOrd<S> for B {
fn partial_cmp(&self, other: &S) -> Option<Ordering> {
let slice: &[u8] = &self.0;
slice.partial_cmp(other.as_ref())
}
}
impl Ord for B {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(&other).unwrap()
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是 - 我如何实现Ord
和Eq
我的自定义DST,以便我可以利用partial_cmp/eq
任何事实AsRef<[u8]>
,但也可以使用它来强制执行Ord
/ Eq
trait实现的边界,就像我struct B
在我的示例中所做的那样?
问题是默认情况下S: AsRef<[u8]>
也限制S
了Sized
类型.您需要使用?Sized
选择退出.
所有泛型类型参数都隐式具有
Sized
绑定,因此?Sized
可以用于选择退出隐式绑定.
以下编译对我来说很好:
use std::cmp::Ordering;
struct A([u8]);
impl AsRef<[u8]> for A {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl<S: AsRef<[u8]> + ?Sized> PartialEq<S> for A {
fn eq(&self, other: &S) -> bool {
self.0.eq(other.as_ref())
}
}
impl Eq for A {}
impl<S: AsRef<[u8]> + ?Sized> PartialOrd<S> for A {
fn partial_cmp(&self, other: &S) -> Option<Ordering> {
let slice: &[u8] = &self.0;
slice.partial_cmp(other.as_ref())
}
}
impl Ord for A {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(&other).unwrap()
}
}
Run Code Online (Sandbox Code Playgroud)