使用特征和泛型重载类似行为
Overloading like behavior using traits and generics
我有一个表示 16 位地址的简单结构:
pub struct Address(u16);
现在我想定义一个方法,它允许我们检查一个地址是否在给定的范围内。此方法接受对另一个地址的引用或 u16 值。此外,我希望能够像这样调用:
let addr = Address{ 0x3fec };
let a1 = Address{ 0x3f00 };
let a2 = Address{ 0x4000 };
if addr.between(&a1, &a2) {
println!("{} lays between {} and {}!", addr, a1, a2);
}
if addr.between(0x3f00, 0x4000) {
println!("{} lays between {} and {}!", addr, a1, a2);
}
我是一个完全的 Rust 初学者,在 Into、From、Borrow、AsRef、Generics 和 Traits 的丛林中有点迷路了。我将如何实施这种行为?第二种情况似乎是一个特殊问题,因为 0x3fff 实际上是一个整数而不是无符号 16 位值。
是否可以通过为同一类型实现通用特征来模仿这种行为?
您可以在您的类型上实现 From<u16>
,并使用通用参数来接受任何可以转换为 Address
的内容,方法是为 Into<Address>
添加特征绑定(Into
gets automatically implemented as soon as you have an implementation for From
).
请注意,我制作了 Address
类型 Copy
因为它只包含一个 u16,这样您就不必费心参考。
#[derive(Clone, Copy, Debug)]
pub struct Address(u16);
impl From<u16> for Address {
fn from(addr: u16) -> Self {
Self(addr)
}
}
impl Address {
pub fn between<T, U>(self, lower: T, upper: U) -> bool
where
T: Into<Address>,
U: Into<Address>,
{
let lower = lower.into();
let upper = upper.into();
lower.0 < self.0 && self.0 < upper.0
}
}
fn main() {
let addr = Address(0x3fec);
let a1 = Address(0x3f00);
let a2 = Address(0x4000);
if addr.between(a1, a2) {
println!("{:?} lays between {:?} and {:?}!", addr, a1, a2);
}
if addr.between(0x3f00, 0x4000) {
println!("{:?} lays between {:?} and {:?}!", addr, a1, a2);
}
}
我有一个表示 16 位地址的简单结构:
pub struct Address(u16);
现在我想定义一个方法,它允许我们检查一个地址是否在给定的范围内。此方法接受对另一个地址的引用或 u16 值。此外,我希望能够像这样调用:
let addr = Address{ 0x3fec };
let a1 = Address{ 0x3f00 };
let a2 = Address{ 0x4000 };
if addr.between(&a1, &a2) {
println!("{} lays between {} and {}!", addr, a1, a2);
}
if addr.between(0x3f00, 0x4000) {
println!("{} lays between {} and {}!", addr, a1, a2);
}
我是一个完全的 Rust 初学者,在 Into、From、Borrow、AsRef、Generics 和 Traits 的丛林中有点迷路了。我将如何实施这种行为?第二种情况似乎是一个特殊问题,因为 0x3fff 实际上是一个整数而不是无符号 16 位值。
是否可以通过为同一类型实现通用特征来模仿这种行为?
您可以在您的类型上实现 From<u16>
,并使用通用参数来接受任何可以转换为 Address
的内容,方法是为 Into<Address>
添加特征绑定(Into
gets automatically implemented as soon as you have an implementation for From
).
请注意,我制作了 Address
类型 Copy
因为它只包含一个 u16,这样您就不必费心参考。
#[derive(Clone, Copy, Debug)]
pub struct Address(u16);
impl From<u16> for Address {
fn from(addr: u16) -> Self {
Self(addr)
}
}
impl Address {
pub fn between<T, U>(self, lower: T, upper: U) -> bool
where
T: Into<Address>,
U: Into<Address>,
{
let lower = lower.into();
let upper = upper.into();
lower.0 < self.0 && self.0 < upper.0
}
}
fn main() {
let addr = Address(0x3fec);
let a1 = Address(0x3f00);
let a2 = Address(0x4000);
if addr.between(a1, a2) {
println!("{:?} lays between {:?} and {:?}!", addr, a1, a2);
}
if addr.between(0x3f00, 0x4000) {
println!("{:?} lays between {:?} and {:?}!", addr, a1, a2);
}
}