特征实现子集的 Rust 特征继承

问题描述 投票:0回答:1

我不确定如何准确地提出这个问题,所以我会通过例子来说明。

我正在使用 bitflags 板条箱,它提供了一个名为

Flags
的特征。标志特征涉及关联类型的存在,例如

pub trait Flags: Sized + 'static {
    /// The underlying bits type.
    type Bits: Bits;

    fn from_bits(bits: Self::Bits) -> Option<Self> {
        ... 
    }

    ...
}

其中 Bits 特征是为以下内容实现的

i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize

然后我希望定义一个继承 Flags 的特征 (

Register
),但添加了在实现时定义关联常量的要求。类似的东西

trait Register: Flags {
    const ADDRESS: u8;

    fn address(&self) -> u8 {
        Self::ADDRESS
    }
}

访问带有附加地址的

Flags
将允许我做一些有用的事情,但是其中一些有用的事情依赖于 Flags 实现来使
Bits
类型成为
u8
。我最终陷入了这样的境地

trait Register: Flags {
    const ADDRESS: u8;

    fn address(&self) -> u8 {
        Self::ADDRESS
    }

    fn do_something(&self) {
        let new_bits_data: u8 = ...;
        *self = Self::from_bits(new_bits_data).unwrap()
    }
}

调用

Self::from_bits()
不起作用,因为我们还不知道
Flags
的特定实现将具有的位的类型。

在我看来,我希望能够仅为已设置的

Register
实现的子集定义
Flags
特征

type Bits = u8;

但我不知道这是否是个好主意,甚至可能。

您对我如何解决这个问题有什么想法,或者是否可以实现我想要的?

我考虑过定义一个特质

Flags_u8
的想法,它与
Flags
相同,但约束为
Bits
类型是
u8
。但我不知道那会是什么样子。

rust design-patterns i2c bitflags
1个回答
0
投票

您可以限制超级特征的关联类型,类似于对任何特征所做的操作:

trait Register: Flags<Bits = u8> { ... }

或者具体方法:

trait Register: Flags {
    const ADDRESS: u8;

    fn address(&self) -> u8 {
        Self::ADDRESS
    }

    fn do_something(&self)
    where
        Self: Flags<Bits = u8>,
    {
        let new_bits_data: u8 = ...;
        *self = Self::from_bits(new_bits_data).unwrap()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.