Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are strings Drop or Copy?

Tags:

rust

ownership

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.

like image 517
user218867 Avatar asked Jun 15 '17 08:06

user218867


People also ask

What happens when you copy a string to another string?

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.

Why does the copy method not create a new string?

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:

What are the alternatives to the copy method in JavaScript?

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.

How do I know how many characters to copy from a string?

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.


1 Answers

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.

like image 183
Matthieu M. Avatar answered Nov 06 '22 15:11

Matthieu M.