为什么结构解构后会出现 drop call?
Why is there a drop call after structure destructuring?
我正在包装一个 C API。为了简化这个问题,我使用 NonNull::dangling
代替。
use std::ptr::NonNull;
struct Foo(NonNull<i32>);
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop: {:?}", self.0);
}
}
struct Moo(NonNull<i32>);
//impl Drop for Moo exists, but not important for question
fn f1() -> Result<Foo, String> {
Ok(Foo(unsafe { NonNull::dangling() }))
}
fn f2() -> Result<Moo, String> {
f1().map(|Foo(x)| Moo(x))//1
}
fn main() {
f2();
}
在第(1)点,我unpack/destructureFoo
。我希望在那之后, Foo::drop
不应该被调用,但由于某种原因 Foo::drop
被打印出来。
解构 (let Struct1 { field1, field2, .. } = struct1;
) 应该阻止 Struct1::drop
的调用我错了吗?
如果将 NonNull
替换为未实现 Copy
的结构,行为会更加清晰:
#[derive(Debug)]
struct NoCopy;
struct Foo(NoCopy);
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop: {:?}", self.0);
}
}
struct Moo(NoCopy);
//impl Drop for Moo exists, but not important for question
fn f1() -> Result<Foo, String> {
Ok(Foo(NoCopy))
}
fn f2() -> Result<Moo, String> {
f1().map(|Foo(x)| Moo(x))//1
}
fn main() {
f2();
}
这会导致此错误:
error[E0509]: cannot move out of type `Foo`, which implements the `Drop` trait
--> src/main.rs:20:15
|
20 | f1().map(|Foo(x)| Moo(x))//1
| ^^^^-^
| | |
| | data moved here
| cannot move out of here
|
note: move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait
--> src/main.rs:20:19
|
20 | f1().map(|Foo(x)| Moo(x))//1
|
因此,在 (1) 中,您从 Foo
中复制了 NonNull
并且 Foo
被删除了。
我正在包装一个 C API。为了简化这个问题,我使用 NonNull::dangling
代替。
use std::ptr::NonNull;
struct Foo(NonNull<i32>);
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop: {:?}", self.0);
}
}
struct Moo(NonNull<i32>);
//impl Drop for Moo exists, but not important for question
fn f1() -> Result<Foo, String> {
Ok(Foo(unsafe { NonNull::dangling() }))
}
fn f2() -> Result<Moo, String> {
f1().map(|Foo(x)| Moo(x))//1
}
fn main() {
f2();
}
在第(1)点,我unpack/destructureFoo
。我希望在那之后, Foo::drop
不应该被调用,但由于某种原因 Foo::drop
被打印出来。
解构 (let Struct1 { field1, field2, .. } = struct1;
) 应该阻止 Struct1::drop
的调用我错了吗?
如果将 NonNull
替换为未实现 Copy
的结构,行为会更加清晰:
#[derive(Debug)]
struct NoCopy;
struct Foo(NoCopy);
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop: {:?}", self.0);
}
}
struct Moo(NoCopy);
//impl Drop for Moo exists, but not important for question
fn f1() -> Result<Foo, String> {
Ok(Foo(NoCopy))
}
fn f2() -> Result<Moo, String> {
f1().map(|Foo(x)| Moo(x))//1
}
fn main() {
f2();
}
这会导致此错误:
error[E0509]: cannot move out of type `Foo`, which implements the `Drop` trait
--> src/main.rs:20:15
|
20 | f1().map(|Foo(x)| Moo(x))//1
| ^^^^-^
| | |
| | data moved here
| cannot move out of here
|
note: move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait
--> src/main.rs:20:19
|
20 | f1().map(|Foo(x)| Moo(x))//1
|
因此,在 (1) 中,您从 Foo
中复制了 NonNull
并且 Foo
被删除了。