jinscoe123
jinscoe123

Reputation: 1739

Derive trait for generic struct only if generic type implements that trait

I'm trying to implement a generic Array type in rust that supports element-wise operations, similar to ndarray. This is just for practice to try to improve my Rust skills. Naturally, I would like to have this type derive certain traits, such as Copy, Clone, PartialEq, Eq, etc., but only if its generic type, T, implements these traits. I have come up with the following two ways of doing this.

// Nice and simple
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Array<T, const N: usize>([T; N]);
// Works, but kind of tedious
pub struct Array<T, const N: usize>([T; N]);

impl<T: Debug, const N: usize> Debug for Array<T, N> {
    ...
}

impl<T: Clone, const N: usize> Clone for Array<T, N> {
    ...
}

...

Both methods seem to work, but the first one is clearly a lot less work; however, I'm worried that there may be some gotchas that I'm not aware of. Are there any issues with the first solution? Is it considered bad practice, and, if so, why?

Finally, what is the idiomatic way to do what I want here?

Upvotes: 0

Views: 368

Answers (1)

Chayim Friedman
Chayim Friedman

Reputation: 71005

The first one is no doubt the best... for a single data type, not for element-wise comparisons.

Debug is safe to derive (unless you want to customize the output). So are Clone and Copy.

But PartialEq, PartialOrd and Ord are just not for you. They, by design, compare two Arrays and give one result - be it a bool or an Ordering - but you need Array<bool> (or Array<Ordering>).

You cannot use the builtin traits for that, you will have to make your own methods.

Upvotes: 2

Related Questions