Q. Why Deref trait can only be implemented for a type T (e.g. String) once while the AsRef trait can be implemented multiple times?

For example, the Deref trait is implemented for String which lets us convert &String into &str implicitly(deref coercion).

And AsRef trait can be implemented for String multiple times so that it can be converted into &[u8], &OsStr, &Path, &str, etc.

Thanks.

This doesn't answer your question, but I'm glad it doesn't. C++ code often has hard-to-track bugs caused by implicit conversions where the compiler found a funny conversion path which doesn't match desired. Deref's limitation reduces surprises.

1 Like

It's because AsRef is generic, but Deref isn't. You don't "implement AsRef", you implement AsRef<T> for some type T. It's not that AsRef can be implemented many times. (No trait can be implemented more than once for any given type.) It's just that AsRef<T> and AsRef<U> are two distinct traits for T != U.

Technically speaking, AsRef is not a trait itself; it's a trait constructor. Parameterizing it with a concrete type will give you a concrete trait.

5 Likes

Let's also tackle it from the perspective of using Deref:

let string = "hello".to_string();
let derefed = &*string;

Other than the Deref impl itself, it's easy to see that there are no other allowances to influence what *expr produces.
In other words, the impl Deref for E (where expr: E) alone must be able to decide what the Deref target is.

3 Likes

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.