Reputation: 85
In code below, I am trying to implement a generic struct. What I want to achieve is, for T whose type is String, print self.x
value, and for all other types, print both self.x
and self.y
.
This question is not relevant to trait
, I only tried to impl
functions for a struct.
use core::fmt::Display;
use core::fmt::Debug;
#[derive(Debug)]
struct Point<T> {
x: T,
y: T
}
impl Point<String> {
fn print(&self) {
println!("{:?}", self.x);
}
}
impl<T: Display + Debug> Point<T> {
fn print(&self) {
println!("{:?}", self.x);
println!("{:?}", self.y);
}
}
fn main() {
let x = Point{x: String::from("123"), y: String::from("456")};
let y = Point{x: 123, y: 456};
//let z = Point{x: vec![1,2,3], y: vec![4,5,6]};
x.print();
y.print();
//z.print();
}
However, I got the compile error below:
error[E0592]: duplicate definitions with name `print`
What is the correct way to achieve it?
Moreover, I also tried to use vectors as x and y(the z
in main), which is not allow, I want to know the reason.
Upvotes: 5
Views: 2362
Reputation: 6779
Rust doesn't support specialization yet, but there is a tracking issue for the same. But your requirement can be satisfied by checking TypeId
.
fn is_string<T: Any>() -> bool {
TypeId::of::<String>() == TypeId::of::<T>()
}
impl<T: Debug + Any> Point<T> {
fn print(&self) {
if is_string::<T>() {
println!("{:?}", self.x);
} else {
println!("{:?}", self.x);
println!("{:?}", self.y);
}
}
}
This code will also work for vectors. In your code you added a trait bound for Display
which is not implemented by Vec
.
Upvotes: 6