5 ms·
The Rust standard library has many examples of exactly this, except with unsafe to assert that the unreachable cases can't happen. A classic example is the Stri
by aliceryhl 6y ago
The Rust standard library has many examples of exactly this, except with unsafe to assert that the unreachable cases can't happen. A classic example is the String type, which is just a newtype around Vec<u8>. Other examples include CStr, NonZeroUsize and PathBuf.
Arguably even File is an example of this. Internally, it's just an integer for the file descriptor.
- the_mitsuhiko 6y ago> has many examples of exactly this Exactly what? I'm not sure what you're referring to here exactly. Generally newtypes in Rust are not used excessively and largely for sensible safety assertions. I don't see people making `EmailAddress(String)` newtypes.
- ChrisSD 6y agoWhy not? That would seem useful if other code depends on having a validated email address.
- the_mitsuhiko 6y agoI point you to the article.
- ChrisSD 6y agoThe article doesn't exactly make a case against it. It even explicitly says it's useful! It just says making a newtype isn't as strong a guarantee as a proper type. Newtypes do work to assert certain checks have already been done and need not be repeated.
- runeks 6y ago> Exactly what? I'm not sure what you're referring to here exactly. "Newtypes as tokens"
- aliceryhl 6y agoOf newtypes. I gave several examples of them. The String type _is_ a newtype that outlaws some of the possible values of the underlying type, namely non-utf8 byte sequences. I wasn't talking about people using Rust, but about the standard library. That said, I have personally used newtypes a reasonable amount, mostly for making sure I don't mess up different kinds of database ids.
- chrisoverzero 6y ago> The String type _is_ a newtype that […] It is not. `NonZeroUsize` is (though in Rust "newtype" is only a pattern or idiom), and its definition (inside of a macro which provides numeric newtypes a bunch of `impl`s) is: pub struct NonZeroUsize(usize); But here's String: pub struct String { vec: Vec<u8>, } …which is a normal `struct` _containing_ a named `Vec<u8>`. Of the types you mentioned, only `NonZeroUsize` conforms to the pattern.
- steveklabnik 6y agoDo you feel that just because the inner value is named, rather than unnamed, it’s no longer a new type? Trying to figure out what line is crossed here.
- chrisoverzero 6y agoI'm going by the Rust documentation: https://doc.rust-lang.org/stable/rust-by-example/generics/new_types.html https://doc.rust-lang.org/stable/rust-by-example/generics/ne... (I was going to be cheeky here, but Git history shows you didn't write any of this part.)
- steveklabnik 6y agoHehe yeah, I mean, I am not 100% sure myself, which is why I asked. There's no real difference between a 1-tuple struct and the regular struct, other than the name. So to me, it feels like either are both newtypes. But, I guess I could see some sort of argument the other way too.