我试图让一个new
构造函数有一个和两个参数,但我似乎无法弄清楚如何做到这一点。这是否有可能呢?
我现在拥有的错误是多个适用的项目在范围内(playground)
trait __Constructor1<T> {
fn new(T) -> Self;
}
trait __Constructor2<T, U> {
fn new(T, U) -> Self;
}
enum MixedInts {
SmallInt(i32),
TwoSmallInts(i32, i32),
}
impl __Constructor1<i32> for MixedInts {
fn new(__0: i32) -> MixedInts {
MixedInts::SmallInt(__0)
}
}
impl __Constructor2<i32, i32> for MixedInts {
fn new(__0: i32, __1: i32) -> MixedInts {
MixedInts::TwoSmallInts(__0, __1)
}
}
fn main() {
let x = MixedInts::new(2i32);
let y = MixedInts::new(2i32, 2i32);
}
答案 0 :(得分:8)
技术上可能,但不是那种实用的方式。您需要使用Rust Universal Function Call Syntax才能消除对new
的调用的歧义。
fn main() {
let x = <MixedInts as __Constructor1<i32>>::new(2i32);
let y = <MixedInts as __Constructor2<i32, i32>>::new(2i32, 2i32);
}
Iron框架有一个有趣的Modifier pattern,我认为可以实现你想要的。虽然它非常聪明,但它最终会让用户感到困惑。
答案 1 :(得分:6)
Rust不支持重载的函数/方法。作为一种变通方法,您可以使用元组在单个参数中接收多个值。然后,您可以定义特征并为该单个参数的可接受类型实现它,该函数将简单地委托给特征的实现。
enum MixedInts {
SmallInt(i32),
TwoSmallInts(i32, i32),
}
trait IntoMixedInts {
fn into(self) -> MixedInts;
}
impl MixedInts {
fn new<A>(args: A) -> MixedInts
where A: IntoMixedInts
{
args.into()
}
}
impl IntoMixedInts for i32 {
fn into(self) -> MixedInts {
MixedInts::SmallInt(self)
}
}
impl IntoMixedInts for (i32, i32) {
fn into(self) -> MixedInts {
MixedInts::TwoSmallInts(self.0, self.1)
}
}
fn main() {
let x = MixedInts::new(2i32);
let y = MixedInts::new((2i32, 2i32));
}
注意:在此示例中,您可以使用标准From
和Into
特征,而不是定义自己的特征。但是,它可能不适用于其他特征,因为一致性规则(规则确保某个特定类型只能存在某个特征的实现)。
enum MixedInts {
SmallInt(i32),
TwoSmallInts(i32, i32),
}
impl MixedInts {
fn new<A>(args: A) -> MixedInts
where A: Into<MixedInts>
{
args.into()
}
}
impl From<i32> for MixedInts {
fn from(a: i32) -> MixedInts {
MixedInts::SmallInt(a)
}
}
impl From<(i32, i32)> for MixedInts {
fn from((a, b): (i32, i32)) -> MixedInts {
MixedInts::TwoSmallInts(a, b)
}
}
fn main() {
let x = MixedInts::new(2i32);
let y = MixedInts::new((2i32, 2i32));
}
答案 2 :(得分:-1)
我建议使用标准库中的From
/ Into
特征。
#[derive(PartialEq, Eq, Debug)]
enum MixedInts {
SmallInt(i32),
TwoSmallInts(i32, i32),
}
impl From<i32> for MixedInts {
fn from(n: i32) -> Self {
MixedInts::SmallInt(n)
}
}
impl From<(i32, i32)> for MixedInts {
fn from((a, b): (i32, i32)) -> Self {
MixedInts::TwoSmallInts(a, b)
}
}
fn main() {
let x: MixedInts = 2_i32.into();
assert_eq!(x, MixedInts::SmallInt(2));
let y: MixedInts = (2_i32, 2_i32).into();
assert_eq!(y, MixedInts::TwoSmallInts(2, 2));
}