我正在为一个API建模,方法重载将是一个很好的 Select .我天真的try 失败了:

// fn attempt_1(_x: i32) {}
// fn attempt_1(_x: f32) {}
// Error: duplicate definition of value `attempt_1`

然后我添加了一个枚举,并完成了以下工作:

enum IntOrFloat {
    Int(i32),
    Float(f32),
}

fn attempt_2(_x: IntOrFloat) {}

fn main() {
    let i: i32 = 1;
    let f: f32 = 3.0;

    // Can't pass the value directly
    // attempt_2(i);
    // attempt_2(f);
    // Error: mismatched types: expected enum `IntOrFloat`

    attempt_2(IntOrFloat::Int(i));
    attempt_2(IntOrFloat::Float(f));
    // Ugly that the caller has to explicitly wrap the parameter
}

通过快速搜索,我找到了found some references个关于重载的话题,所有这些话题似乎都以"我们不允许这样做,但try 一下"结尾.所以我试着:

enum IntOrFloat {
    Int(i32),
    Float(f32),
}

trait IntOrFloatTrait {
    fn to_int_or_float(&self) -> IntOrFloat;
}

impl IntOrFloatTrait for i32 {
    fn to_int_or_float(&self) -> IntOrFloat {
        IntOrFloat::Int(*self)
    }
}

impl IntOrFloatTrait for f32 {
    fn to_int_or_float(&self) -> IntOrFloat {
        IntOrFloat::Float(*self)
    }
}

fn attempt_3(_x: &dyn IntOrFloatTrait) {}

fn main() {
    let i: i32 = 1;
    let f: f32 = 3.0;

    attempt_3(&i);
    attempt_3(&f);
    // Better, but the caller still has to explicitly take the reference
}

这是最接近方法重载的方法吗?有没有更干净的方法?

推荐答案

是的,有,而且你几乎已经拿到了.trait是一种方法,但你不需要trait对象,使用泛型:

#[derive(Debug)]
enum IntOrFloat {
    Int(i32),
    Float(f32),
}

trait IntOrFloatTrait {
    fn to_int_or_float(&self) -> IntOrFloat;
}

impl IntOrFloatTrait for i32 {
    fn to_int_or_float(&self) -> IntOrFloat {
        IntOrFloat::Int(*self)
    }
}

impl IntOrFloatTrait for f32 {
    fn to_int_or_float(&self) -> IntOrFloat {
        IntOrFloat::Float(*self)
    }
}

fn attempt_4<T: IntOrFloatTrait>(x: T) {
    let v = x.to_int_or_float();
    println!("{:?}", v);
}

fn main() {
    let i: i32 = 1;
    let f: f32 = 3.0;

    attempt_4(i);
    attempt_4(f);
}

看到它工作了吗.

Rust相关问答推荐

移植带有可变borrow 的C代码-卸载期间错误(nappgui示例)

在HashMap中插入Vacant条目的可变借位问题

是否有可能同时避免不兼容的不透明类型和代码重复?

为什么允许我们将可变引用转换为不可变引用?

用 rust 蚀中的future 展望 struct 的future

在Rust中判断编译时是否无法访问

完全匹配包含大小写的整数范围(&Q;)

解析程序无法在Cargo 发布中 Select 依赖版本

具有多个键的 HashMap

Rust 中的复合 `HashSet` 操作或如何在 Rust 中获得 `HashSet` 的显式差异/并集

Rust 文件未编译到 dll 中

Rust 为什么被视为borrow ?

Rust与_有何区别?

Rust 编译器不统一在 if let 表达式的分支中都 impl Future 的类型

如何将 Rust 字符串转换为 i8(c_char) 数组?

Rust 异步和 AsRef 未被发送

Rustfmt 是否有明确类型的选项?

如何构建包含本地依赖项的 docker 镜像?

Rust 生命周期:不能在方法内重新borrow 可变字段

如何在宏中的多个参数上编写嵌套循环?