字符串是 Drop 还是 Copy?

Are strings Drop or Copy?

我正在了解 Rust 的所有权。我的测试表明,字符串文字在变量赋值时被复制,而 String 个实例被移动。这是否意味着 StringDrop 而字符串文字是 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();
}

rustc variable_assign_test.rs -o a.out 编译,运行 用 ./a.out

编译

如果test_tuple_assign()的最后一行没有被注释掉,变量eric.

会报错value used here after move

.

需要说明的是,所有不可变引用 (&T) 都是 Copy,而可变引用 (&mut T) 只是移动的。 &'static str,字符串文字的类型,只是 &T 的一个特例,一个不可变的引用,因此是 Copy.

另一方面,String 实例是为其内容动态分配的缓冲区的唯一所有者。这可以防止它成为 Copy(单一所有者)并要求它实现 Drop(以释放动态分配的缓冲区)。

不过,在细节上,String 不直接实现 Drop,而是围绕 Vec<u8> 的包装器,它本身实现了 Drop。行为是相同的,只是 StringDrop 实现是自动生成的,而 Vec<u8> 的实现是 manually written.