* `|` (`|…| expr`): closures. See [Closures].
* `|=` (`var |= expr`): bitwise or & assignment. Overloadable (`BitOrAssign`).
* `||` (`expr || expr`): logical or.
-* `_`: "ignored" pattern binding. See [Patterns (Ignoring bindings)].
+* `_`: "ignored" pattern binding (see [Patterns (Ignoring bindings)]). Also used to make integer-literals readable (see [Reference (Integer literals)]).
## Other Syntax
[Primitive Types (Tuples)]: primitive-types.html#tuples
[Raw Pointers]: raw-pointers.html
[Reference (Byte String Literals)]: ../reference.html#byte-string-literals
+[Reference (Integer literals)]: ../reference.html#integer-literals
[Reference (Raw Byte String Literals)]: ../reference.html#raw-byte-string-literals
[Reference (Raw String Literals)]: ../reference.html#raw-string-literals
[References and Borrowing]: references-and-borrowing.html
}
```
-Unlike the previous example it *appears* that everything is exactly as we
+Unlike the previous example, it *appears* that everything is exactly as we
want. Every generic argument to Vec shows up in at least one field.
Good to go!
* includes a `PhantomData<T>`
* auto-derives Send/Sync as if T was contained
* marks the pointer as NonZero for the null-pointer optimization
-
A number of [attributes](#ffi-attributes) control the behavior of external blocks.
By default external blocks assume that the library they are calling uses the
-standard C "cdecl" ABI. Other ABIs may be specified using an `abi` string, as
-shown here:
+standard C ABI on the specific platform. Other ABIs may be specified using an
+`abi` string, as shown here:
```ignore
// Interface to the Windows API
extern "stdcall" { }
```
+There are three ABI strings which are cross-platform, and which all compilers
+are guaranteed to support:
+
+* `extern "Rust"` -- The default ABI when you write a normal `fn foo()` in any
+ Rust code.
+* `extern "C"` -- This is the same as `extern fn foo()`; whatever the default
+ your C compiler supports.
+* `extern "system"` -- Usually the same as `extern "C"`, except on Win32, in
+ which case it's `"stdcall"`, or what you should use to link to the Windows API
+ itself
+
+There are also some platform-specific ABI strings:
+
+* `extern "cdecl"` -- The default for x86\_32 C code.
+* `extern "stdcall"` -- The default for the Win32 API on x86\_32.
+* `extern "win64"` -- The default for C code on x86\_64 Windows.
+* `extern "aapcs"` -- The default for ARM.
+* `extern "fastcall"` -- The `fastcall` ABI -- corresponds to MSVC's
+ `__fastcall` and GCC and clang's `__attribute__((fastcall))`
+* `extern "vectorcall"` -- The `vectorcall` ABI -- corresponds to MSVC's
+ `__vectorcall` and clang's `__attribute__((vectorcall))`
+
+Finally, there are some rustc-specific ABI strings:
+
+* `extern "rust-intrinsic"` -- The ABI of rustc intrinsics.
+* `extern "rust-call"` -- The ABI of the Fn::call trait functions.
+* `extern "platform-intrinsic"` -- Specific platform intrinsics -- like, for
+ example, `sqrt` -- have this ABI. You should never have to deal with it.
+
The `link` attribute allows the name of the library to be specified. When
specified the compiler will attempt to link against the native library of the
specified name.
///
/// # Examples
///
- /// Print the slice split by numbers divisible by 3 (i.e. `[10, 40]`,
- /// `[20]`, `[50]`):
+ /// ```
+ /// let slice = [10, 40, 33, 20];
+ /// let mut iter = slice.split(|num| num % 3 == 0);
///
+ /// assert_eq!(iter.next().unwrap(), &[10, 40]);
+ /// assert_eq!(iter.next().unwrap(), &[20]);
+ /// assert!(iter.next().is_none());
/// ```
- /// let v = [10, 40, 30, 20, 60, 50];
///
- /// for group in v.split(|num| *num % 3 == 0) {
- /// println!("{:?}", group);
- /// }
+ /// If the first element is matched, an empty slice will be the first item
+ /// returned by the iterator. Similarly, if the last element in the slice
+ /// is matched, an empty slice will be the last item returned by the
+ /// iterator:
+ ///
+ /// ```
+ /// let slice = [10, 40, 33];
+ /// let mut iter = slice.split(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[10, 40]);
+ /// assert_eq!(iter.next().unwrap(), &[]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// If two matched elements are directly adjacent, an empty slice will be
+ /// present between them:
+ ///
+ /// ```
+ /// let slice = [10, 6, 33, 20];
+ /// let mut iter = slice.split(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[10]);
+ /// assert_eq!(iter.next().unwrap(), &[]);
+ /// assert_eq!(iter.next().unwrap(), &[20]);
+ /// assert!(iter.next().is_none());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
/// Retrieves an element in the `VecDeque` by index.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Examples
///
/// ```
/// Retrieves an element in the `VecDeque` mutably by index.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Examples
///
/// ```
///
/// Fails if there is no element with either index.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Examples
///
/// ```
///
/// Returns `None` if `index` is out of bounds.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Examples
///
/// ```
///
/// Returns `None` if `index` is out of bounds.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Examples
///
/// ```
/// end is closer to the insertion point will be moved to make room,
/// and all the affected elements will be moved to new positions.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Panics
///
/// Panics if `index` is greater than `VecDeque`'s length
/// room, and all the affected elements will be moved to new positions.
/// Returns `None` if `index` is out of bounds.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Examples
///
/// ```
///
/// Note that the capacity of `self` does not change.
///
+ /// Element at index 0 is the front of the queue.
+ ///
/// # Panics
///
/// Panics if `at > len`
/// Moves a value out of scope without running drop glue.
pub fn forget<T>(_: T) -> ();
- /// Unsafely transforms a value of one type into a value of another type.
+ /// Reinterprets the bits of a value of one type as another type; both types
+ /// must have the same size. Neither the original, nor the result, may be an
+ /// [invalid value] (../../nomicon/meet-safe-and-unsafe.html).
///
- /// Both types must have the same size.
+ /// `transmute` is semantically equivalent to a bitwise move of one type
+ /// into another. It copies the bits from the destination type into the
+ /// source type, then forgets the original. It's equivalent to C's `memcpy`
+ /// under the hood, just like `transmute_copy`.
+ ///
+ /// `transmute` is incredibly unsafe. There are a vast number of ways to
+ /// cause undefined behavior with this function. `transmute` should be
+ /// the absolute last resort.
+ ///
+ /// The [nomicon](../../nomicon/transmutes.html) has additional
+ /// documentation.
///
/// # Examples
///
+ /// There are a few things that `transmute` is really useful for.
+ ///
+ /// Getting the bitpattern of a floating point type (or, more generally,
+ /// type punning, when `T` and `U` aren't pointers):
+ ///
/// ```
- /// use std::mem;
+ /// let bitpattern = unsafe {
+ /// std::mem::transmute::<f32, u32>(1.0)
+ /// };
+ /// assert_eq!(bitpattern, 0x3F800000);
+ /// ```
+ ///
+ /// Turning a pointer into a function pointer:
+ ///
+ /// ```
+ /// fn foo() -> i32 {
+ /// 0
+ /// }
+ /// let pointer = foo as *const ();
+ /// let function = unsafe {
+ /// std::mem::transmute::<*const (), fn() -> i32>(pointer)
+ /// };
+ /// assert_eq!(function(), 0);
+ /// ```
+ ///
+ /// Extending a lifetime, or shortening an invariant lifetime; this is
+ /// advanced, very unsafe rust:
+ ///
+ /// ```
+ /// struct R<'a>(&'a i32);
+ /// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
+ /// std::mem::transmute::<R<'b>, R<'static>>(r)
+ /// }
+ ///
+ /// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
+ /// -> &'b mut R<'c> {
+ /// std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
+ /// }
+ /// ```
+ ///
+ /// # Alternatives
+ ///
+ /// However, many uses of `transmute` can be achieved through other means.
+ /// `transmute` can transform any type into any other, with just the caveat
+ /// that they're the same size, and often interesting results occur. Below
+ /// are common applications of `transmute` which can be replaced with safe
+ /// applications of `as`:
///
- /// let array: &[u8] = unsafe { mem::transmute("Rust") };
- /// assert_eq!(array, [82, 117, 115, 116]);
+ /// Turning a pointer into a `usize`:
+ ///
+ /// ```
+ /// let ptr = &0;
+ /// let ptr_num_transmute = unsafe {
+ /// std::mem::transmute::<&i32, usize>(ptr)
+ /// };
+ /// // Use an `as` cast instead
+ /// let ptr_num_cast = ptr as *const i32 as usize;
+ /// ```
+ ///
+ /// Turning a `*mut T` into an `&mut T`:
+ ///
+ /// ```
+ /// let ptr: *mut i32 = &mut 0;
+ /// let ref_transmuted = unsafe {
+ /// std::mem::transmute::<*mut i32, &mut i32>(ptr)
+ /// };
+ /// // Use a reborrow instead
+ /// let ref_casted = unsafe { &mut *ptr };
+ /// ```
+ ///
+ /// Turning an `&mut T` into an `&mut U`:
+ ///
+ /// ```
+ /// let ptr = &mut 0;
+ /// let val_transmuted = unsafe {
+ /// std::mem::transmute::<&mut i32, &mut u32>(ptr)
+ /// };
+ /// // Now, put together `as` and reborrowing - note the chaining of `as`
+ /// // `as` is not transitive
+ /// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
+ /// ```
+ ///
+ /// Turning an `&str` into an `&[u8]`:
+ ///
+ /// ```
+ /// // this is not a good way to do this.
+ /// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
+ /// assert_eq!(slice, &[82, 117, 115, 116]);
+ /// // You could use `str::as_bytes`
+ /// let slice = "Rust".as_bytes();
+ /// assert_eq!(slice, &[82, 117, 115, 116]);
+ /// // Or, just use a byte string, if you have control over the string
+ /// // literal
+ /// assert_eq!(b"Rust", &[82, 117, 115, 116]);
+ /// ```
+ ///
+ /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`:
+ ///
+ /// ```
+ /// let store = [0, 1, 2, 3];
+ /// let mut v_orig = store.iter().collect::<Vec<&i32>>();
+ /// // Using transmute: this is Undefined Behavior, and a bad idea.
+ /// // However, it is no-copy.
+ /// let v_transmuted = unsafe {
+ /// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
+ /// v_orig.clone())
+ /// };
+ /// // This is the suggested, safe way.
+ /// // It does copy the entire Vector, though, into a new array.
+ /// let v_collected = v_orig.clone()
+ /// .into_iter()
+ /// .map(|r| Some(r))
+ /// .collect::<Vec<Option<&i32>>>();
+ /// // The no-copy, unsafe way, still using transmute, but not UB.
+ /// // This is equivalent to the original, but safer, and reuses the
+ /// // same Vec internals. Therefore the new inner type must have the
+ /// // exact same size, and the same or lesser alignment, as the old
+ /// // type. The same caveats exist for this method as transmute, for
+ /// // the original inner type (`&i32`) to the converted inner type
+ /// // (`Option<&i32>`), so read the nomicon pages linked above.
+ /// let v_from_raw = unsafe {
+ /// Vec::from_raw_parts(v_orig.as_mut_ptr(),
+ /// v_orig.len(),
+ /// v_orig.capacity())
+ /// };
+ /// std::mem::forget(v_orig);
+ /// ```
+ ///
+ /// Implementing `split_at_mut`:
+ ///
+ /// ```
+ /// use std::{slice, mem};
+ /// // There are multiple ways to do this; and there are multiple problems
+ /// // with the following, transmute, way.
+ /// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
+ /// -> (&mut [T], &mut [T]) {
+ /// let len = slice.len();
+ /// assert!(mid <= len);
+ /// unsafe {
+ /// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
+ /// // first: transmute is not typesafe; all it checks is that T and
+ /// // U are of the same size. Second, right here, you have two
+ /// // mutable references pointing to the same memory.
+ /// (&mut slice[0..mid], &mut slice2[mid..len])
+ /// }
+ /// }
+ /// // This gets rid of the typesafety problems; `&mut *` will *only* give
+ /// // you an `&mut T` from an `&mut T` or `*mut T`.
+ /// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
+ /// -> (&mut [T], &mut [T]) {
+ /// let len = slice.len();
+ /// assert!(mid <= len);
+ /// unsafe {
+ /// let slice2 = &mut *(slice as *mut [T]);
+ /// // however, you still have two mutable references pointing to
+ /// // the same memory.
+ /// (&mut slice[0..mid], &mut slice2[mid..len])
+ /// }
+ /// }
+ /// // This is how the standard library does it. This is the best method, if
+ /// // you need to do something like this
+ /// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
+ /// -> (&mut [T], &mut [T]) {
+ /// let len = slice.len();
+ /// assert!(mid <= len);
+ /// unsafe {
+ /// let ptr = slice.as_mut_ptr();
+ /// // This now has three mutable references pointing at the same
+ /// // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
+ /// // `slice` is never used after `let ptr = ...`, and so one can
+ /// // treat it as "dead", and therefore, you only have two real
+ /// // mutable slices.
+ /// (slice::from_raw_parts_mut(ptr, mid),
+ /// slice::from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
+ /// }
+ /// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn transmute<T, U>(e: T) -> U;
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait DoubleEndedIterator: Iterator {
- /// An iterator able to yield elements from both ends.
+ /// Removes and returns an element from the end of the iterator.
///
- /// As this is the only method for this trait, the [trait-level] docs
- /// contain more details.
+ /// Returns `None` when there are no more elements.
+ ///
+ /// The [trait-level] docs contain more details.
///
/// [trait-level]: trait.DoubleEndedIterator.html
///
/// }
///
/// for val in map.values() {
- /// print!("{}", val);
+ /// println!("{}", val);
/// }
/// ```
#[stable(feature = "map_values_mut", since = "1.10.0")]
}
/// A view into a single location in a map, which may be vacant or occupied.
+/// This enum is constructed from the [`entry`] method on [`HashMap`].
+///
+/// [`HashMap`]: struct.HashMap.html
+/// [`entry`]: struct.HashMap.html#method.entry
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Entry<'a, K: 'a, V: 'a> {
/// An occupied Entry.
}
/// A view into a single occupied location in a HashMap.
+/// It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
key: Option<K>,
}
/// A view into a single empty location in a HashMap.
+/// It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K: 'a, V: 'a> {
hash: SafeHash,
#[stable(feature = "rust1", since = "1.0.0")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// assert_eq!(map["poneyland"], 12);
+ ///
+ /// *map.entry("poneyland").or_insert(12) += 10;
+ /// assert_eq!(map["poneyland"], 22);
+ /// ```
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
#[stable(feature = "rust1", since = "1.0.0")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, String> = HashMap::new();
+ /// let s = "hoho".to_owned();
+ ///
+ /// map.entry("poneyland").or_insert_with(|| s);
+ ///
+ /// assert_eq!(map["poneyland"], "hoho".to_owned());
+ /// ```
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
}
/// Returns a reference to this entry's key.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
+ /// ```
#[stable(feature = "map_entry_keys", since = "1.10.0")]
pub fn key(&self) -> &K {
match *self {
impl<'a, K, V> OccupiedEntry<'a, K, V> {
/// Gets a reference to the key in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
+ /// ```
#[stable(feature = "map_entry_keys", since = "1.10.0")]
pub fn key(&self) -> &K {
self.elem.read().0
}
/// Take the ownership of the key and value from the map.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(map_entry_recover_keys)]
+ ///
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// if let Entry::Occupied(o) = map.entry("poneyland") {
+ /// // We delete the entry from the map.
+ /// o.remove_pair();
+ /// }
+ ///
+ /// assert_eq!(map.contains_key("poneyland"), false);
+ /// ```
#[unstable(feature = "map_entry_recover_keys", issue = "34285")]
pub fn remove_pair(self) -> (K, V) {
pop_internal(self.elem)
}
/// Gets a reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// if let Entry::Occupied(o) = map.entry("poneyland") {
+ /// assert_eq!(o.get(), &12);
+ /// }
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self) -> &V {
self.elem.read().1
}
/// Gets a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// assert_eq!(map["poneyland"], 12);
+ /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
+ /// *o.get_mut() += 10;
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 22);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut V {
self.elem.read_mut().1
}
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
- /// with a lifetime bound to the map itself
+ /// with a lifetime bound to the map itself.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// assert_eq!(map["poneyland"], 12);
+ /// if let Entry::Occupied(o) = map.entry("poneyland") {
+ /// *o.into_mut() += 10;
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 22);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_mut(self) -> &'a mut V {
self.elem.into_mut_refs().1
}
- /// Sets the value of the entry, and returns the entry's old value
+ /// Sets the value of the entry, and returns the entry's old value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
+ /// assert_eq!(o.insert(15), 12);
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 15);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn insert(&mut self, mut value: V) -> V {
let old_value = self.get_mut();
value
}
- /// Takes the value out of the entry, and returns it
+ /// Takes the value out of the entry, and returns it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// map.entry("poneyland").or_insert(12);
+ ///
+ /// if let Entry::Occupied(o) = map.entry("poneyland") {
+ /// assert_eq!(o.remove(), 12);
+ /// }
+ ///
+ /// assert_eq!(map.contains_key("poneyland"), false);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove(self) -> V {
pop_internal(self.elem).1
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
/// Gets a reference to the key that would be used when inserting a value
- /// through the VacantEntry.
+ /// through the `VacantEntry`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
+ /// ```
#[stable(feature = "map_entry_keys", since = "1.10.0")]
pub fn key(&self) -> &K {
&self.key
}
/// Take ownership of the key.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(map_entry_recover_keys)]
+ ///
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ ///
+ /// if let Entry::Vacant(v) = map.entry("poneyland") {
+ /// v.into_key();
+ /// }
+ /// ```
#[unstable(feature = "map_entry_recover_keys", issue = "34285")]
pub fn into_key(self) -> K {
self.key
}
/// Sets the value of the entry with the VacantEntry's key,
- /// and returns a mutable reference to it
+ /// and returns a mutable reference to it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::Entry;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ ///
+ /// if let Entry::Vacant(o) = map.entry("poneyland") {
+ /// o.insert(37);
+ /// }
+ /// assert_eq!(map["poneyland"], 37);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn insert(self, value: V) -> &'a mut V {
match self.elem {
/// Metadata information about a file.
///
-/// This structure is returned from the `metadata` function or method and
+/// This structure is returned from the [`metadata`] function or method and
/// represents known metadata about a file such as its permissions, size,
/// modification times, etc.
+///
+/// [`metadata`]: fn.metadata.html
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct Metadata(fs_imp::FileAttr);
/// Iterator over the entries in a directory.
///
-/// This iterator is returned from the `read_dir` function of this module and
-/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
+/// This iterator is returned from the [`read_dir`] function of this module and
+/// will yield instances of `io::Result<DirEntry>`. Through a [`DirEntry`]
/// information like the entry's path and possibly other metadata can be
/// learned.
///
+/// [`read_dir`]: fn.read_dir.html
+/// [`DirEntry`]: struct.DirEntry.html
+///
/// # Errors
///
-/// This `io::Result` will be an `Err` if there's some sort of intermittent
+/// This [`io::Result`] will be an `Err` if there's some sort of intermittent
/// IO error during iteration.
+///
+/// [`io::Result`]: ../io/type.Result.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ReadDir(fs_imp::ReadDir);
-/// Entries returned by the `ReadDir` iterator.
+/// Entries returned by the [`ReadDir`] iterator.
+///
+/// [`ReadDir`]: struct.ReadDir.html
///
/// An instance of `DirEntry` represents an entry inside of a directory on the
/// filesystem. Each entry can be inspected via methods to learn about the full
/// Options and flags which can be used to configure how a file is opened.
///
-/// This builder exposes the ability to configure how a `File` is opened and
-/// what operations are permitted on the open file. The `File::open` and
-/// `File::create` methods are aliases for commonly used options using this
+/// This builder exposes the ability to configure how a [`File`] is opened and
+/// what operations are permitted on the open file. The [`File::open`] and
+/// [`File::create`] methods are aliases for commonly used options using this
/// builder.
///
-/// Generally speaking, when using `OpenOptions`, you'll first call `new()`,
-/// then chain calls to methods to set each option, then call `open()`, passing
-/// the path of the file you're trying to open. This will give you a
+/// [`File`]: struct.File.html
+/// [`File::open`]: struct.File.html#method.open
+/// [`File::create`]: struct.File.html#method.create
+///
+/// Generally speaking, when using `OpenOptions`, you'll first call [`new()`],
+/// then chain calls to methods to set each option, then call [`open()`],
+/// passing the path of the file you're trying to open. This will give you a
/// [`io::Result`][result] with a [`File`][file] inside that you can further
/// operate on.
///
+/// [`new()`]: struct.OpenOptions.html#method.new
+/// [`open()`]: struct.OpenOptions.html#method.open
/// [result]: ../io/type.Result.html
/// [file]: struct.File.html
///
/// Representation of the various permissions on a file.
///
-/// This module only currently provides one bit of information, `readonly`,
+/// This module only currently provides one bit of information, [`readonly`],
/// which is exposed on all currently supported platforms. Unix-specific
/// functionality, such as mode bits, is available through the
/// `os::unix::PermissionsExt` trait.
+///
+/// [`readonly`]: struct.Permissions.html#method.readonly
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Permissions(fs_imp::FilePermissions);
impl File {
/// Attempts to open a file in read-only mode.
///
- /// See the `OpenOptions::open` method for more details.
+ /// See the [`OpenOptions::open`] method for more details.
///
/// # Errors
///
/// This function will return an error if `path` does not already exist.
- /// Other errors may also be returned according to `OpenOptions::open`.
+ /// Other errors may also be returned according to [`OpenOptions::open`].
+ ///
+ /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
///
/// # Examples
///
/// This function will create a file if it does not exist,
/// and will truncate it if it does.
///
- /// See the `OpenOptions::open` function for more details.
+ /// See the [`OpenOptions::open`] function for more details.
+ ///
+ /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
///
/// # Examples
///
self.inner.fsync()
}
- /// This function is similar to `sync_all`, except that it may not
+ /// This function is similar to [`sync_all`], except that it may not
/// synchronize file metadata to the filesystem.
///
/// This is intended for use cases that must synchronize content, but don't
/// operations.
///
/// Note that some platforms may simply implement this in terms of
- /// `sync_all`.
+ /// [`sync_all`].
+ ///
+ /// [`sync_all`]: struct.File.html#method.sync_all
///
/// # Examples
///
/// The returned `File` is a reference to the same state that this object
/// references. Both handles will read and write with the same cursor
/// position.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::open("foo.txt"));
+ /// let file_copy = try!(f.try_clone());
+ /// # Ok(())
+ /// # }
+ /// ```
#[stable(feature = "file_try_clone", since = "1.9.0")]
pub fn try_clone(&self) -> io::Result<File> {
Ok(File {
/// On Windows this function is cheap to call (no extra system calls
/// needed), but on Unix platforms this function is the equivalent of
/// calling `symlink_metadata` on the path.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::fs;
+ ///
+ /// if let Ok(entries) = fs::read_dir(".") {
+ /// for entry in entries {
+ /// if let Ok(entry) = entry {
+ /// // Here, `entry` is a `DirEntry`.
+ /// if let Ok(metadata) = entry.metadata() {
+ /// // Now let's show our entry's permissions!
+ /// println!("{:?}: {:?}", entry.path(), metadata.permissions());
+ /// } else {
+ /// println!("Couldn't get metadata for {:?}", entry.path());
+ /// }
+ /// }
+ /// }
+ /// }
+ /// ```
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn metadata(&self) -> io::Result<Metadata> {
self.0.metadata().map(Metadata)
/// On Windows and most Unix platforms this function is free (no extra
/// system calls needed), but some Unix platforms may require the equivalent
/// call to `symlink_metadata` to learn about the target file type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::fs;
+ ///
+ /// if let Ok(entries) = fs::read_dir(".") {
+ /// for entry in entries {
+ /// if let Ok(entry) = entry {
+ /// // Here, `entry` is a `DirEntry`.
+ /// if let Ok(file_type) = entry.file_type() {
+ /// // Now let's show our entry's file type!
+ /// println!("{:?}: {:?}", entry.path(), file_type);
+ /// } else {
+ /// println!("Couldn't get file type for {:?}", entry.path());
+ /// }
+ /// }
+ /// }
+ /// }
+ /// ```
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn file_type(&self) -> io::Result<FileType> {
self.0.file_type().map(FileType)
/// Returns the bare file name of this directory entry without any other
/// leading path component.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::fs;
+ ///
+ /// if let Ok(entries) = fs::read_dir(".") {
+ /// for entry in entries {
+ /// if let Ok(entry) = entry {
+ /// // Here, `entry` is a `DirEntry`.
+ /// println!("{:?}", entry.file_name());
+ /// }
+ /// }
+ /// }
+ /// ```
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn file_name(&self) -> OsString {
self.0.file_name()
impl DirBuilder {
/// Creates a new set of options with default mode/security settings for all
/// platforms and also non-recursive.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::fs::DirBuilder;
+ ///
+ /// let builder = DirBuilder::new();
+ /// ```
#[stable(feature = "dir_builder", since = "1.6.0")]
pub fn new() -> DirBuilder {
DirBuilder {
/// all parent directories if they do not exist with the same security and
/// permissions settings.
///
- /// This option defaults to `false`
+ /// This option defaults to `false`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::fs::DirBuilder;
+ ///
+ /// let mut builder = DirBuilder::new();
+ /// builder.recursive(true);
+ /// ```
#[stable(feature = "dir_builder", since = "1.6.0")]
pub fn recursive(&mut self, recursive: bool) -> &mut Self {
self.recursive = recursive;
pub trait DirEntryExt {
/// Returns the underlying `d_ino` field in the contained `dirent`
/// structure.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::fs;
+ /// use std::os::unix::fs::DirEntryExt;
+ ///
+ /// if let Ok(entries) = fs::read_dir(".") {
+ /// for entry in entries {
+ /// if let Ok(entry) = entry {
+ /// // Here, `entry` is a `DirEntry`.
+ /// println!("{:?}: {}", entry.file_name(), entry.ino());
+ /// }
+ /// }
+ /// }
+ /// ```
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
fn ino(&self) -> u64;
}
pub trait DirBuilderExt {
/// Sets the mode to create new directories with. This option defaults to
/// 0o777.
+ ///
+ /// # Examples
+ ///
+ /// ```ignore
+ /// use std::fs::DirBuilder;
+ /// use std::os::unix::fs::DirBuilderExt;
+ ///
+ /// let mut builder = DirBuilder::new();
+ /// builder.mode(0o755);
+ /// ```
#[stable(feature = "dir_builder", since = "1.6.0")]
fn mode(&mut self, mode: u32) -> &mut Self;
}