字符串是 Drop 还是 Copy?
Are strings Drop or Copy?
我正在了解 Rust 的所有权。我的测试表明,字符串文字在变量赋值时被复制,而 String
个实例被移动。这是否意味着 String
是 Drop
而字符串文字是 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
。行为是相同的,只是 String
的 Drop
实现是自动生成的,而 Vec<u8>
的实现是 manually written.
我正在了解 Rust 的所有权。我的测试表明,字符串文字在变量赋值时被复制,而 String
个实例被移动。这是否意味着 String
是 Drop
而字符串文字是 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
。行为是相同的,只是 String
的 Drop
实现是自动生成的,而 Vec<u8>
的实现是 manually written.