首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我要得到一个‘特性绑定’[T]:std::marker::Sized`‘当我尝试在不大小的类型上手动实现Ord和Eq时,Sized`’是不满意的?

为什么我要得到一个‘特性绑定’[T]:std::marker::Sized`‘当我尝试在不大小的类型上手动实现Ord和Eq时,Sized`’是不满意的?
EN

Stack Overflow用户
提问于 2016-10-13 14:23:04
回答 1查看 1.6K关注 0票数 8

在创建存储DST的结构(例如,原始切片)时,我可以使用普通的#[derive(Eq, PartialEq, Ord, PartialOrd)]工具在我的类型中获得这个特性的实现:

代码语言:javascript
复制
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct A([u8]);

但是,如果我手动实现它们,编译器就会抱怨我的类型没有实现Sized

代码语言:javascript
复制
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()
    }
}

编译器结果:

代码语言:javascript
复制
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`

如果我创建了一个具有固定大小的类型的变体(例如,通过将其转换为一个固定大小的数组),那么我可以手动实现这些特性没有问题。

代码语言:javascript
复制
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()
    }
}

这里有一个操场链接,显示了这个问题。

我的问题是--如何在我的自定义DST上实现OrdEq,这样我就可以利用这样一个事实:我可以通过任何AsRef<[u8]>来实现partial_cmp/eq,但也可以使用它来强制执行Ord/Eq特性实现的边界,就像我在我的示例中使用struct B一样?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-13 14:48:37

问题是,默认情况下,S: AsRef<[u8]>还将S限制为Sized类型。您需要使用?Sized来选择退出。

所有泛型类型参数都隐式地具有Sized绑定,因此可以使用?Sized选择退出隐式绑定。

从“锈书”

以下是对我来说很好的编译:

代码语言:javascript
复制
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()
    }
}

演示

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40023706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档