函数重载技巧-编译器无法选择调用哪个函数



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,所以特质ApplyCopyapply是唯一可以调用的,而&NotCopy(34)是参考,因为NotCopy不是Copy,所以只有ApplyRefapply可以调用。

这是Rust编译器的限制还是我遗漏了什么?

这是Rust编译器的限制还是我遗漏了什么?

虽然有编译器的魔力&在它们周围的特殊情况下,在基本级别,引用仍然是一个适当的类型,因此任何T都可以是隐藏的&Q,引用类型可以实现特性。

NotCopy不是Copy时,&NotCopyCopy。因此&NotCopy与这两种情况相匹配。

最新更新