I'm learning about Rust's ownership. My tests show that string literals are copied on variable assignment while String
instances are moved. Does that mean that String
is Drop
while string literals are Copy
?
variable_assign_test.rs
// variable assign test,
// assign variable on stack to another,
fn test_stack_assign() {
let x = 5;
let y = x; // data duplicated on stack,
println!("x = {}, y = {}", x, y); // it's ok,
}
// assign variable on heap to another,
fn test_heap_assign() {
let s1 = String::from("hello");
let s2 = s1; // now s1 is invalid, should not use it any more,
// println!("{}", s1); // this won't compile,
println!("s2 = {}", s2); // it's ok,
}
fn test_tuple_assign() {
let pa = (1, 2);
let pb = pa;
println!("pa = {:?}, pb = {:?}", pa, pb); // it's ok,
// tuple that contains string literal,
let name_monica = "monica";
let monica = (11, name_monica);
let monica2 = monica;
println!("monica = {:?}, monica2 = {:?}", monica, monica2);
// tuple that contains String instance,
let name_eric = String::from("eric");
let eric = (12, name_eric);
let eric2 = eric; // eric is invalid now,
// println!("eric = {:?}, eric = {:?}", eric, eric2); // this won't compile,
}
fn main() {
test_stack_assign();
test_heap_assign();
test_tuple_assign();
}
Compile with rustc variable_assign_test.rs -o a.out
and run with ./a.out
If the last line of test_tuple_assign()
is uncommented, it will get an error value used here after move
for the variable eric
.
A new string with the same value as str. str is null. The Copy method returns a String object that has the same value as the original string but represents a different object reference. It differs from an assignment operation, which assigns an existing string reference to an additional object variable.
In particular, because of changes in string interning in .NET Core 3.0, in some cases the Copy method will not create a new string but will simply return a reference to an existing interned string. Depending on Why you want to call the Copy method, there are a number of alternatives:
Depending on Why you want to call the Copy method, there are a number of alternatives: If you want a different string instance to use in an operation that modifies the string, use the original string instance. Because strings are immutable, the string operation creates a new string instance, and the original string remains unaffected.
Number of characters to copy (if the string is shorter, as many characters as possible are copied). Position of the first character to be copied. If this is greater than the string length, it throws out_of_range. Note: The first character in the string is denoted by a value of 0 (not 1 ). The number of characters copied to the array pointed by s.
Yes.
To be clear, all immutable references (&T
) are Copy
, while the mutable ones (&mut T
) are move only. &'static str
, the type of string literals, is just one special case of &T
, an immutable reference, and therefore is Copy
.
On the other hand, a String
instance is the single owner of a dynamically allocated buffer for its content. This prevents it from being Copy
(single owner) and requires it to implement Drop
(to free the dynamically allocated buffer).
In details, though, String
does not implement Drop
directly, but instead is a wrapper around a Vec<u8>
which itself implements Drop
. The behavior is identical, it's just that the Drop
implementation of String
is auto-generated, whereas the one from Vec<u8>
is manually written.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With