5 ms·
Deref for Vec<T> and String is fine because they are owning containers that decay to their "view" types (slices). Strings and vectors own memory, while views bo
by qalmakka 3y ago
Deref for Vec<T> and String is fine because they are owning containers that decay to their "view" types (slices). Strings and vectors own memory, while views borrow it and can be used to operate on them without reallocating or moving the container itself, treating it as a contiguous list of values. A similar relationship exists between C++'s `std::string` and `std::string_view`, and `std::vector` and `std::span`.
IMHO there the logic behind that is very clear and makes a lot of sense. I think it's natural that view-related traits (the ones who operate on the elements of a contiguous area of memory) should be associated with slices, while memory-related ones (the ones that operate on an owning container) should be implemented on the owning types. If you mix them up, you are bound to mess up first and foremost because _it is not logically sound_. You don't need to own a string in order to check if all of its ASCII characters are all caps, for instance, because it's an operation that's also valid on any array of bytes, without the whole concept of "owning memory".
- edbaskerville 3y agoThank you article, parent, GP. You've saved me just in time from never having read the Deref documentation properly. I have some code to delete before I make this mistake again.
- tialaramex 3y ago> You don't need to own a string in order to check if all of its ASCII characters are all caps, for instance, because it's an operation that's also valid on any array of bytes, without the whole concept of "owning memory". Interestingly you can ask whether a string is ASCII, "this".is_ascii() is a predicate which does exactly that, but for what I think is your question, "are they all ASCII caps?" you'd need to go via an iterator and a lambda: "THIS".bytes().all(|b| b.is_ascii_uppercase()) The iterator is because there is no provision of each such predicate over the whole string, which seems reasonable (the character class predicates are provided on u8 (ASCII only), and on char (all of them)), but the lambda is due to Rust's 1.0 compatibility commitment plus an unfortunate historical choice. If not for compatibility we'd fix it so you could just write "THIS".bytes().all(u8::is_ascii_uppercase)
- saghm 3y agoAm I correct in thinking this is the type of thing change that fits the criteria to be implemented in a new edition? Assuming the issue is the same one I often run into (i.e. 'a versus for<'a>), it seems like special casing this for closures passed as arguments would be quite nice, but the fact that it wasn't done for 2018 or 2021 makes me think that maybe it's not something that would qualify for introducing in this way.
- tialaramex 3y agoIt's not "just" syntax, so it couldn't "just" be a new edition, but I suppose it's conceivable that a hack could be invented and then the old behaviour grandfathered into prior editions as was done for impl IntoIterator for [T; N] in 2021 Edition. That's a heavy lift though, you may need to carry this special code around in every compiler, forever, and I haven't even figured out what such code should look like, it might be really hard to even write it.
- saghm 3y agoGood to know! I appreciate the insight
- 3836293648 3y agoHow would removing the lambda affect back compat?