将`Deref`实现为返回复合结构的字段是否很习惯?

时间:2018-10-12 03:18:22

标签: rust

我有:

struct Id;
struct Url;
struct IdAndUrl {
    id: Id,
    url: Url,
}

我希望能够在仅需要IdAndUrl的地方使用Id。为了消除噪音,我可以使用impl Deref<Id> for IdAndUrl

这是一种好习惯吗?

2 个答案:

答案 0 :(得分:6)

Deref的目的是实现指针类型。应该将指向T的指针转换为T,因此取消引用指针的感觉是“自然的”。使用它在不相关的类型之间进行转换似乎令人困惑。

我建议您改为添加一种吸气剂方法id()

答案 1 :(得分:6)

确实存在与DerefDerefMut相关的接近官方的指南。根据Rust API指南中的C-DEREF“只有智能指针才能实现DerefDerefMut。” 您建议使用Deref会导致多个问题,因此强烈建议不要这样做。

Deref没有类型参数,但是有关联的类型。要实现它,必须按下面的代码完成,但是永远不能为其他属性实现。

// don't try this at home!
impl Deref for IdAndUrl {
    type Target = Id;

    fn deref(&self) -> &Self::Target { &self.id }
}

此外,Deref实现通过反引用强制从目标类型公开方法,并使用您可能不想在此处使用的接口污染结构。

一个人可以查看其他转换特征(即FromAsRefBorrow),看看它们是否有意义(C-CONV-TRAITS)。但是根据我的解释,这些都没有道理。正如另一个答案中所建议的那样,在这里使用简单的吸气剂是理想的:

impl IdAndUrl {
    fn id(&self) -> &Id { &self.id }
}