3 ms·
The tl;dr doesn't quite make sense to me. To me the core difference is that a Box<str> takes one less word on the stack, because by virtue of the str being immu
by dochtman 4y ago
The tl;dr doesn't quite make sense to me. To me the core difference is that a Box<str> takes one less word on the stack, because by virtue of the str being immutable it doesn't need to track the capacity of the allocation as distinct from the length. This is analogous to Box<[u8]> vs Vec<u8> (and in fact those are the same data types except for the guarantee of valid UTF-8).
- tialaramex 4y agoOne notable difference is that ToOwned for &str gives you a String, whereas ToOwned for &[u8] gives you a [u8] by cloning the slice you have. In fact all four standard library types that are ToOwned without invoking Clone are more or less strings (str, CStr, OsStr, Path)
- afdbcreid 4y agoWhat? No: https://doc.rust-lang.org/1.61.0/src/alloc/slice.rs.html#854-878 https://doc.rust-lang.org/1.61.0/src/alloc/slice.rs.html#854.... ToOwned for [T] gives you Vec<T>.
- tialaramex 4y agoHuh. TIL Actually now that I think harder about this, WTF did I think was really going on here before. If we clone the slice to make an array, where does the array go? We don't know how big that array is, so we can't put it on the stack. Yeah, that was crazy. Thanks for pointing it out.
- kzrdude 4y agoPerspective on ToOwned: It's just Clone with an extension to a number of DST types that can't be Clone themselves. They are dynamically sized types, hence no surprise that they are string-like.
- tines 4y agoC++ programmer here: which one guarantees valid utf8, and why would a primitive container make guarantees about the values it's storing?
- lifthrasiir 4y agoEverything labelled as "string" is a valid UTF-8 string in Rust, and to my knowledge this decision was made very early in the history of Rust (before 0.1). Many "modern" languages (including modern enough C++) have a distinction between Unicode strings and byte strings however they are called and Rust just followed the suit.
- M2Ys4U 4y agoOsStr and OsString aren't necessarily UTF-8, the data for those are "in the operating system’s preferred representation". str/String and CStr/CString are defined as UTF-8, though.
- puffoflogic 4y ago> in the operating system’s preferred representation This is unfortunately misleading and a common misconception about OsStr. The documentation now explains: > OsStr losslessly represents a borrowed reference to a platform string. However, this representation is not necessarily in a form native to the platform What this means is that valid sequences of Unicode scalars are encoded as utf8 in OsStr on both Windows and Linux. The difference between OsStr and str is that the former can round-trip with the native encoding; that means that for Windows, there's a special way it encodes unpaired surrogates (wtf8) and on Linux it's actually just an arbitrary byte sequence. This choice of representation means that on every platform: you can always borrow an OsStr from a str (as_ref) and you can sometimes borrow a str from an OsStr (to_str). This cross-borrowing wouldn't be possible if OsStr were UCS-2 on Windows.
- Animats 4y ago"str" and "String" guarantee UTF-8. To make a String from an array of bytes, call pub fn from_utf8(vec: Vec<u8, Global>) -> Result<String, FromUtf8Error> which consumes the input Vec and returns it unmodified, if it's valid UTF-8,, or reports an error, if it's not. There are a number of related functions in this family. Such as pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> which takes in a slice of bytes and checks if it's a UTF-8 string. If it is, it returns the original str. Otherwise it makes a copy with any errors replaced with the Unicode error character. Vec<u8> and array slices such as &[u8] are primitive containers - they can store any sequence of u8 values. String is more like an object with access methods.