mirror of
https://github.com/rust-lang/rust
synced 2024-11-02 09:18:18 +00:00
Rollup merge of #25861 - tringenbach:master, r=steveklabnik
This adds an example from mem::swap, and provides some suggested uses of this function. This is my attempt to summarize the answers to a question I asked on reddit http://www.reddit.com/r/rust/comments/37jcul/what_is_forget_for/ and add the answers to the documentation so that no one else has to google or ask the question again.
This commit is contained in:
commit
1999d759f7
1 changed files with 49 additions and 7 deletions
|
@ -52,20 +52,61 @@
|
|||
/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally)
|
||||
/// * Panicking destructors are likely to leak local resources
|
||||
///
|
||||
/// # When To Use
|
||||
///
|
||||
/// There's only a few reasons to use this function. They mainly come
|
||||
/// up in unsafe code or FFI code.
|
||||
///
|
||||
/// * You have an uninitialized value, perhaps for performance reasons, and
|
||||
/// need to prevent the destructor from running on it.
|
||||
/// * You have two copies of a value (like `std::mem::swap`), but need the
|
||||
/// destructor to only run once to prevent a double free.
|
||||
/// * Transferring resources across FFI boundries.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Leak some heap memory by never deallocating it.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::mem;
|
||||
///
|
||||
/// let heap_memory = Box::new(3);
|
||||
/// mem::forget(heap_memory);
|
||||
/// ```
|
||||
///
|
||||
/// Leak an I/O object, never closing the file.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use std::mem;
|
||||
/// use std::fs::File;
|
||||
///
|
||||
/// // Leak some heap memory by never deallocating it
|
||||
/// let heap_memory = Box::new(3);
|
||||
/// mem::forget(heap_memory);
|
||||
///
|
||||
/// // Leak an I/O object, never closing the file
|
||||
/// let file = File::open("foo.txt").unwrap();
|
||||
/// mem::forget(file);
|
||||
/// ```
|
||||
///
|
||||
/// The swap function uses forget to good effect.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::mem;
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// fn swap<T>(x: &mut T, y: &mut T) {
|
||||
/// unsafe {
|
||||
/// // Give ourselves some scratch space to work with
|
||||
/// let mut t: T = mem::uninitialized();
|
||||
///
|
||||
/// // Perform the swap, `&mut` pointers never alias
|
||||
/// ptr::copy_nonoverlapping(&*x, &mut t, 1);
|
||||
/// ptr::copy_nonoverlapping(&*y, x, 1);
|
||||
/// ptr::copy_nonoverlapping(&t, y, 1);
|
||||
///
|
||||
/// // y and t now point to the same thing, but we need to completely
|
||||
/// // forget `t` because we do not want to run the destructor for `T`
|
||||
/// // on its value, which is still owned somewhere outside this function.
|
||||
/// mem::forget(t);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn forget<T>(t: T) {
|
||||
unsafe { intrinsics::forget(t) }
|
||||
|
@ -267,8 +308,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
|
|||
ptr::copy_nonoverlapping(&*y, x, 1);
|
||||
ptr::copy_nonoverlapping(&t, y, 1);
|
||||
|
||||
// y and t now point to the same thing, but we need to completely forget `t`
|
||||
// because it's no longer relevant.
|
||||
// y and t now point to the same thing, but we need to completely
|
||||
// forget `t` because we do not want to run the destructor for `T`
|
||||
// on its value, which is still owned somewhere outside this function.
|
||||
forget(t);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue