rust - 函数重载技巧-编译器无法选择要调用的函数

标签 rust

Rust没有函数重载:您不能使用相同的名称但使用不同的参数来定义多个函数。
但是,我发现了以下技巧,使它看起来像是函数重载。请注意,如何在main()中调用不同类型的example.apply(...):

struct Example;

trait Apply<T, R> {
    fn apply(&self, value: T) -> R;
}

impl Apply<i32, i32> for Example {
    fn apply(&self, value: i32) -> i32 {
        value * 2
    }
}

impl Apply<&str, String> for Example {
    fn apply(&self, value: &str) -> String {
        format!("Hello, {}", value)
    }
}

fn main() {
    let example = Example;

    // Looks like function overloading!
    let one = example.apply(12);
    let two = example.apply("World");

    println!("{}", one);
    println!("{}", two);
}
现在,我想制作Apply特征的两个不同版本:一个用于Copy的值,另一个用于非Copy的值:
struct Example;

struct NotCopy(i32);

// For types which are Copy
trait ApplyCopy<T: Copy, R> {
    fn apply(&self, value: T) -> R;
}

// For types which are not Copy
trait ApplyRef<T, R> {
    fn apply(&self, value: &T) -> R;
}

impl ApplyCopy<i32, i32> for Example {
    fn apply(&self, value: i32) -> i32 {
        value * 2
    }
}

impl ApplyRef<NotCopy, String> for Example {
    fn apply(&self, value: &NotCopy) -> String {
        format!("NotCopy({})", value.0)
    }
}
但是,当我尝试使用它时,出现错误:
fn main() {
    let example = Example;

    let one = example.apply(12);            // Error: multiple `apply` found
    let two = example.apply(&NotCopy(34));  // Error: multiple `apply` found

    println!("{}", one);
    println!("{}", two);
}
错误消息之一:
error[E0034]: multiple applicable items in scope
  --> src/main.rs:30:23
   |
30 |     let one = example.apply(12);            // Error: multiple `apply` found
   |                       ^^^^^ multiple `apply` found
   |
note: candidate #1 is defined in an impl of the trait `ApplyCopy` for the type `Example`
  --> src/main.rs:16:5
   |
16 |     fn apply(&self, value: i32) -> i32 {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `ApplyRef` for the type `Example`
  --> src/main.rs:22:5
   |
22 |     fn apply(&self, value: &NotCopy) -> String {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the associated function for candidate #1
   |
30 |     let one = ApplyCopy::apply(&example, 12);            // Error: multiple `apply` found
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the associated function for candidate #2
   |
30 |     let one = ApplyRef::apply(&example, 12);            // Error: multiple `apply` found
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
编译器提示它不知道要调用哪个apply函数。我希望它能够做出选择:i32不是引用,而是Copy,因此只能调用trait applyApplyCopy,并且&NotCopy(34)是引用,并且由于NotCopy不是Copy,所以只能可以调用applyApplyRef
这是Rust编译器的局限性还是我缺少什么?

最佳答案

Is this a limitation of the Rust compiler or am I missing something?


尽管在它们周围有编译器魔术和特殊的大写字母,但从根本上来说,引用仍然是正确的类型,因此任何T都可以是其背后的&Q,并且引用类型可以实现特征。
NotCopy不是Copy时,是 &NotCopy is Copy 。因此,&NotCopy可以匹配这两种情况。

关于rust - 函数重载技巧-编译器无法选择要调用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62873219/

相关文章:

rust - 如何在 Cargo.toml 中包含未发布的依赖项/库?

url - `url_serde`要求不相关的特征范围

rust - 如何内省(introspection) Rust 类型的所有可用方法和成员?

rust - 为什么传递给 flat_map 且没有类型注释的闭包可以编译,而带有注释的闭包则不能编译?

元组中的 Rust trait 对象 --- 预期的 trait 对象,找到的类型

rust - 使用泛型时, `From` 的实现如何冲突?

concurrency - 如何使用 Rust 和 Tokio 构建多个并发服务器?

rust - 为什么这个生命周期函数是可能的?

rust - 借用对结构中属性的引用

error-handling - 为什么当我返回一个错误类型时它没有被隐式转换?