Implementing `AsRef` for types not storing the reference

I have a type (enum) that doesn't store any reference to another type but can be converted to a static reference to it (by matching on variants and returning the appropriate static). Would it still make sense to implement AsRef?

It feels like AsRef should be used whenever the reference is stored in the type itself but nothing in the documentation says so. Yeah, it technically works, I'm more concerned about it being potentially surprising/confusing.

Note that in my case a trait is actually needed anyway - some functions should be able to accept both types, internally converting, so the question can be viewed as "use AsRef or a custom trait?" but I'm also interested in general cases. (A possible answer is "Yeah, it's confusing, you shouldn't do it most of the time but making your own trait is worse".)

One pretty good reason to use AsRef is it also gives conversions from boxes, arcs and other stuff, including containers defined by external crates (presumably those implement these standard traits).

Do you think you'd be surprised/confused if you saw such code? Do you have any interesting arguments for/against?

Prior arts:

AsRef is absolutely desirable if you can:

  • implement it without expensive allocations or copying and
  • return a &[u8]

A very good use case may be serializing the structure, the ones that implement AsRef provide almost "free" byte representations, so we can just stream them wherever it's needed. So, if you can implement such as_ref() that it doesn't allocate any memory and return a &[u8], go ahead, it's not confusing at all!

If you need to allocate some data, to_bytes or to_vec is probably less confusing, as "to_..." hints at more expensive call.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.