3 ms·
I can't say examples like this sell me on Rust, coming from C++. I need to manually to_string(), every single time I want to use strings? And that bizarre scop
by Night_Thastus 2y ago
I can't say examples like this sell me on Rust, coming from C++. I need to manually to_string(), every single time I want to use strings?
And that bizarre scoping of Person p feels very un-intuitive. How would you work around that if you need to keep using it after show()? (Which is an extremely common use case)
- Slyfox33 2y ago"Dave" by itself is basically the same as in c++, just a pointer to a string literal. Dave.to_string() is like std::string {"Dave"}, it allocates a heap based string from said literal. So you can use "Dave" perfectly fine if you just want a string literal.
- winrid 2y agoto_string() gives you an owned string (like std::string) vs a borrowed string slice (kind of like char*). If you already have an owned string you don't need to do that obviously If you need to keep using Person after calling show() then don't pass ownership to show() - you can pass a reference or a mutable reference, or use Rc<> etc
- aseipp 2y agoA raw string literal gets embedded into the binary's data section at compile time, just like it would in C or C++. What this means is that the type of the string literal is actually a reference (to an underlying memory address). And so it has type '&str' which reflects the fact you are using a reference to a value that exists somewhere else. The type 'String' is instead an "owned" type, which means that it is not a reference, and instead a complete value and has a copy of the data. to_string() will create a String (owned value) from a &str (reference) by copying it. This is no different than if you had a global static compile-time string in C and you wanted to modify or update it: you would memcpy the global (statically allocated) string into a local buffer of the appropriate size and then modify it and pass it onward to other things that need it. You would not modify the static string in place. In short, no, you do not need to_string() every time you want to work with a string. You need it to convert a reference type to an owned type. Rust's type system is just used here to codify the more implicit parts of C or C++'s behavior that you are already familiar with, but the underlying bits and bytes behave as you would expect coming from C++. > And that bizarre scoping of Person p feels very un-intuitive. How would you work around that if you need to keep using it after show() You take a reference just like you would in C++. Possibly a mutable reference if you want to modify the thing and then use it afterwords. This is in the article as the "Advanced rust example" at the end, it's right there and not hidden or anything. It isn't really bizarre honestly; it's a matter of defaults. The difference is that Rust uses move-by-default, not copy-by-default or ref-by-default. Every time you write `x = y` for a given owned type, you are doing a move of `y` and into `x` and thus making `y` invalid. let g: &str = "Austin"; // statically allocated string let x: String = g.to_string(); // do a copy let y: String = x; // no copy, x is moved Once you internalize this a lot more stuff will make sense, or at least it did for me.