Hello, folks.
I'm new to Rust and trying to wrap my head around generics and traits interaction. As I understand, I can limit the type my generic is defined for by using type bounds. Like this:
fn dummy<T: A+B>(arg1: T) {}
where A and B some traits. Is it correctly to think about traits A and B as kind of sets of types and about A+B as of set intersection? If so, what's about set union?
Is it possible to define a function over a union (of disjoint) traits, something like this?
trait A {
fn method_a(self: &Self) -> String;
}
trait C {
fn method_c(self: &Self) -> String;
}
fn func_b<T: A>(x: T) {
println!("func_b for A: {}", x.method_a())
}
fn func_b<T: C>(x: T) {
println!("func_b for C: {}", x.method_c())
}
Yes, that's a good way to think about it. I believe the code implementing the type system might even treat it that way.
No, it's not possible to do that in Rust. There should only be one instance of a particular "item" (i.e. struct, function, constant, etc.) with a particular name in a particular module, so it's not possible to define multiple func_b() functions.
To explain why, think about what would happen if I had some type which implements bothA and C... There would be no way to know which version of func_b() to call, and because downstream users can implement any trait they want on their types, you would have no way to prevent those situations.
Yeah, I saw this code is being rejected by a compiler. I just don't understand whether it is for the fundamental reason or just for the sake of simplicity. My initial thought was that allowing this code should not be a problem, because afaik generic function is being specialized for a particular type and the compiler can check whether traits intersect for the type in question or not. But maybe it's doomed to become too confusing for users...