Idiomatic getters for Copy types?

I have a type like the following:

#[derive(Copy, Clone)]
struct Wrapper<T: Copy>(T);

If I didn't have the T: Copy bound, I'd probably write getters like:

impl<T> Wrapper<T> {
    fn get(&self) -> &T;
    fn into_inner(self) -> T;
}

However, since T: Copy, this is redundant - I don't need both. Is there a generally accepted way to provide getters in this situation? Any examples from the standard library or ecosystem, perhaps?

If T is known to be small enough, I'd use get(&self) -> T (e.g. Cell does it).

2 Likes

Sidenote: don't place bounds on generic arguments on types; it usually ends up being unnecessarily restrictive and it doesn't gain much. Constrain impl blocks if necessary instead.

5 Likes

True, although Cell also provides into_inner.

Yeah, I'm oversimplifying a bit. In reality, there are multiple types like this, and they all implement a single trait which has the bound MyTrait<T>: Copy. The question is actually about methods on that trait, not inherent methods.

I don't see why it shouldn't be fn get(self) -> T i.e. with a self argument. std::num::Wrapping is an example of a newtype wrapper that uses self methods.

1 Like

Side-sidenote: Unless the type layout needs to store an associated type, which isn’t the case here.

3 Likes

Oh that strikes me as very clean, thanks!

Cell provides this for any type while it provides get(&self) -> T only if T: Copy. You can do a similar thing if you don't restrict the T on the struct definition, as @H2CO3 suggested.