-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Option | helpful methods
In addition to working with Option efficient,
some additional methods to be provided...
Implementations grouped by meaning
- Querying the contained values
///
/// Returns `true` if the option is a [`Some`] value.
///
/// # Examples
///
/// ```
/// let x: Option<u32> = Some(2);
/// assert_eq!(x.is_some(), true);
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_some(), false);
/// ```
pub const fn is_some(&self) -> bool {
matches!(*self, Some(_))
}
///
/// Returns `true` if the option is a [`Some`] and the value inside of it matches a predicate.
///
/// # Examples
///
/// ```
/// let x: Option<u32> = Some(2);
/// assert_eq!(x.is_some_and(|x| x > 1), true);
///
/// let x: Option<u32> = Some(0);
/// assert_eq!(x.is_some_and(|x| x > 1), false);
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_some_and(|x| x > 1), false);
/// ```
pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
match self {
None => false,
Some(x) => f(x),
}
}
///
/// Returns `true` if the option is a [`None`] value.
///
/// # Examples
///
/// ```
/// let x: Option<u32> = Some(2);
/// assert_eq!(x.is_none(), false);
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_none(), true);
/// ```
pub const fn is_none(&self) -> bool {
!self.is_some()
}
///
/// Returns `true` if the option is a [`None`] or the value inside of it matches a predicate.
///
/// # Examples
///
/// ```
/// let x: Option<u32> = Some(2);
/// assert_eq!(x.is_none_or(|x| x > 1), true);
///
/// let x: Option<u32> = Some(0);
/// assert_eq!(x.is_none_or(|x| x > 1), false);
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_none_or(|x| x > 1), true);
/// ```
pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
match self {
None => true,
Some(x) => f(x),
}
}-
Extracting contained values
- expect
///
/// Returns the contained [`Some`] value, consuming the `self` value.
///
/// # Panics
///
/// Panics if the value is a [`None`] with a custom panic message provided by
/// `msg`.
///
/// # Examples
///
/// ```
/// let x = Some("value");
/// assert_eq!(x.expect("fruits are healthy"), "value");
/// ```
///
/// ```should_panic
/// let x: Option<&str> = None;
/// x.expect("fruits are healthy"); // panics with `fruits are healthy`
/// ```
///
/// # Recommended Message Style
///
/// We recommend that `expect` messages are used to describe the reason you
/// _expect_ the `Option` should be `Some`.
///
/// ```should_panic
/// # let slice: &[u8] = &[];
/// let item = slice.get(0)
/// .expect("slice should not be empty");
/// ```
///
/// **Hint**: If you're having trouble remembering how to phrase expect
/// error messages remember to focus on the word "should" as in "env
/// variable should be set by blah" or "the given binary should be available
/// and executable by the current user".
///
/// For more detail on expect message styles and the reasoning behind our
/// recommendation please refer to the section on ["Common Message
/// Styles"](../../std/error/index.html#common-message-styles) in the [`std::error`](../../std/error/index.html) module docs.
pub const fn expect(self, msg: &str) -> T {
match self {
Some(val) => val,
None => expect_failed(msg),
}
}- unwrap
///
/// Returns the contained [`Some`] value, consuming the `self` value.
///
/// Because this function may panic, its use is generally discouraged.
/// Instead, prefer to use pattern matching and handle the [`None`]
/// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
/// [`unwrap_or_default`].
///
/// [`unwrap_or`]: Option::unwrap_or
/// [`unwrap_or_else`]: Option::unwrap_or_else
/// [`unwrap_or_default`]: Option::unwrap_or_default
///
/// # Panics
///
/// Panics if the self value equals [`None`].
///
/// # Examples
///
/// ```
/// let x = Some("air");
/// assert_eq!(x.unwrap(), "air");
/// ```
///
/// ```should_panic
/// let x: Option<&str> = None;
/// assert_eq!(x.unwrap(), "air"); // fails
/// ```
pub const fn unwrap(self) -> T {
match self {
Some(val) => val,
None => unwrap_failed(),
}
}- unwrap_or
///
/// Returns the contained [`Some`] value or a provided default.
///
/// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing
/// the result of a function call, it is recommended to use [`unwrap_or_else`],
/// which is lazily evaluated.
///
/// [`unwrap_or_else`]: Option::unwrap_or_else
///
/// # Examples
///
/// ```
/// assert_eq!(Some("car").unwrap_or("bike"), "car");
/// assert_eq!(None.unwrap_or("bike"), "bike");
/// ```
pub fn unwrap_or(self, default: T) -> T {
match self {
Some(x) => x,
None => default,
}
}- unwrap_or_else
///
/// Returns the contained [`Some`] value or computes it from a closure.
///
/// # Examples
///
/// ```
/// let k = 10;
/// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4);
/// assert_eq!(None.unwrap_or_else(|| 2 * k), 20);
/// ```
pub fn unwrap_or_else<F>(self, f: F) -> T
where
F: FnOnce() -> T,
{
match self {
Some(x) => x,
None => f(),
}
}- unwrap_or_default
///
/// Returns the contained [`Some`] value or a default.
///
/// Consumes the `self` argument then, if [`Some`], returns the contained
/// value, otherwise if [`None`], returns the [default value] for that
/// type.
///
/// # Examples
///
/// ```
/// let x: Option<u32> = None;
/// let y: Option<u32> = Some(12);
///
/// assert_eq!(x.unwrap_or_default(), 0);
/// assert_eq!(y.unwrap_or_default(), 12);
/// ```
///
/// [default value]: Default::default
/// [`parse`]: str::parse
/// [`FromStr`]: crate::str::FromStr
- [ ] unwrap_or_default
pub fn unwrap_or_default(self) -> T
where
T: Default,
{
match self {
Some(x) => x,
None => T::default(),
}
}- Transforming contained values
///
/// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value (if `Some`) or returns `None` (if `None`).
///
/// # Examples
///
/// Calculates the length of an <code>Option<[String]></code> as an
/// <code>Option<[usize]></code>, consuming the original:
///
/// [String]: ../../std/string/struct.String.html "String"
/// ```
/// let maybe_some_string = Some(String::from("Hello, World!"));
/// // `Option::map` takes self *by value*, consuming `maybe_some_string`
/// let maybe_some_len = maybe_some_string.map(|s| s.len());
/// assert_eq!(maybe_some_len, Some(13));
///
/// let x: Option<&str> = None;
/// assert_eq!(x.map(|s| s.len()), None);
/// ```
pub fn map<U, F>(self, f: F) -> Option<U>
where
F: FnOnce(T) -> U,
{
match self {
Some(x) => Some(f(x)),
None => None,
}
}
///
/// Calls a function with a reference to the contained value if [`Some`].
///
/// Returns the original option.
///
/// # Examples
///
/// ```
/// let list = vec![1, 2, 3];
///
/// // prints "got: 2"
/// let x = list
/// .get(1)
/// .inspect(|x| println!("got: {x}"))
/// .expect("list should be long enough");
///
/// // prints nothing
/// list.get(5).inspect(|x| println!("got: {x}"));
/// ```
pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
if let Some(ref x) = self {
f(x);
}
self
}
///
/// Returns the provided default result (if none),
/// or applies a function to the contained value (if any).
///
/// Arguments passed to `map_or` are eagerly evaluated; if you are passing
/// the result of a function call, it is recommended to use [`map_or_else`],
/// which is lazily evaluated.
///
/// [`map_or_else`]: Option::map_or_else
///
/// # Examples
///
/// ```
/// let x = Some("foo");
/// assert_eq!(x.map_or(42, |v| v.len()), 3);
///
/// let x: Option<&str> = None;
/// assert_eq!(x.map_or(42, |v| v.len()), 42);
/// ```
pub fn map_or<U, F>(self, default: U, f: F) -> U
where
F: FnOnce(T) -> U,
{
match self {
Some(t) => f(t),
None => default,
}
}
///
/// Computes a default function result (if none), or
/// applies a different function to the contained value (if any).
///
/// # Basic examples
///
/// ```
/// let k = 21;
///
/// let x = Some("foo");
/// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 3);
///
/// let x: Option<&str> = None;
/// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42);
/// ```
///
/// # Handling a Result-based fallback
///
/// A somewhat common occurrence when dealing with optional values
/// in combination with [`Result<T, E>`] is the case where one wants to invoke
/// a fallible fallback if the option is not present. This example
/// parses a command line argument (if present), or the contents of a file to
/// an integer. However, unlike accessing the command line argument, reading
/// the file is fallible, so it must be wrapped with `Ok`.
///
/// ```no_run
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let v: u64 = std::env::args()
/// .nth(1)
/// .map_or_else(|| std::fs::read_to_string("/etc/someconfig.conf"), Ok)?
/// .parse()?;
/// # Ok(())
/// # }
/// ```
pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
where
D: FnOnce() -> U,
F: FnOnce(T) -> U,
{
match self {
Some(t) => f(t),
None => default(),
}
}
///
/// Transforms the `Option<T>` into a [`Result<T, E>`], mapping [`Some(v)`] to
/// [`Ok(v)`] and [`None`] to [`Err(err)`].
///
/// Arguments passed to `ok_or` are eagerly evaluated; if you are passing the
/// result of a function call, it is recommended to use [`ok_or_else`], which is
/// lazily evaluated.
///
/// [`Ok(v)`]: Ok
/// [`Err(err)`]: Err
/// [`Some(v)`]: Some
/// [`ok_or_else`]: Option::ok_or_else
///
/// # Examples
///
/// ```
/// let x = Some("foo");
/// assert_eq!(x.ok_or(0), Ok("foo"));
///
/// let x: Option<&str> = None;
/// assert_eq!(x.ok_or(0), Err(0));
/// ```
pub fn ok_or<E>(self, err: E) -> Result<T, E> {
match self {
Some(v) => Ok(v),
None => Err(err),
}
}
///
/// Transforms the `Option<T>` into a [`Result<T, E>`], mapping [`Some(v)`] to
/// [`Ok(v)`] and [`None`] to [`Err(err())`].
///
/// [`Ok(v)`]: Ok
/// [`Err(err())`]: Err
/// [`Some(v)`]: Some
///
/// # Examples
///
/// ```
/// let x = Some("foo");
/// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
///
/// let x: Option<&str> = None;
/// assert_eq!(x.ok_or_else(|| 0), Err(0));
/// ```
pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
where
F: FnOnce() -> E,
{
match self {
Some(v) => Ok(v),
None => Err(err()),
}
}
///
/// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
///
/// Leaves the original Option in-place, creating a new one with a reference
/// to the original one, additionally coercing the contents via [`Deref`].
///
/// # Examples
///
/// ```
/// let x: Option<String> = Some("hey".to_owned());
/// assert_eq!(x.as_deref(), Some("hey"));
///
/// let x: Option<String> = None;
/// assert_eq!(x.as_deref(), None);
/// ```
pub fn as_deref(&self) -> Option<&T::Target>
where
T: Deref,
{
match self.as_ref() {
Some(t) => Some(t.deref()),
None => None,
}
}
///
/// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
///
/// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
/// the inner type's [`Deref::Target`] type.
///
/// # Examples
///
/// ```
/// let mut x: Option<String> = Some("hey".to_owned());
/// assert_eq!(x.as_deref_mut().map(|x| {
/// x.make_ascii_uppercase();
/// x
/// }), Some("HEY".to_owned().as_mut_str()));
/// ```
pub fn as_deref_mut(&mut self) -> Option<&mut T::Target>
where
T: DerefMut,
{
match self.as_mut() {
Some(t) => Some(t.deref_mut()),
None => None,
}
}
///
/// Returns a slice of the contained value, if any. If this is `None`, an
/// empty slice is returned. This can be useful to have a single type of
/// iterator over an `Option` or slice.
///
/// Note: Should you have an `Option<&T>` and wish to get a slice of `T`,
/// you can unpack it via `opt.map_or(&[], std::slice::from_ref)`.
///
/// # Examples
///
/// ```rust
/// assert_eq!(
/// [Some(1234).as_slice(), None.as_slice()],
/// [&[1234][..], &[][..]],
/// );
/// ```
///
/// The inverse of this function is (discounting
/// borrowing) [`[_]::first`](slice::first):
///
/// ```rust
/// for i in [Some(1234_u16), None] {
/// assert_eq!(i.as_ref(), i.as_slice().first());
/// }
/// ```
pub const fn as_slice(&self) -> &[T] {
unsafe {
slice::from_raw_parts(
(self as *const Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
self.len(),
)
}
}- Iterator constructors
///
/// Returns an iterator over the possibly contained value.
///
/// # Examples
///
/// ```
/// let x = Some(4);
/// assert_eq!(x.iter().next(), Some(&4));
///
/// let x: Option<u32> = None;
/// assert_eq!(x.iter().next(), None);
/// ```
pub const fn iter(&self) -> Iter<'_, T> {
Iter { inner: Item { opt: self.as_ref() } }
}
- [ ] **Boolean operations on the values, eager and lazy**
///
/// Returns [`None`] if the option is [`None`], otherwise returns `optb`.
///
/// Arguments passed to `and` are eagerly evaluated; if you are passing the
/// result of a function call, it is recommended to use [`and_then`], which is
/// lazily evaluated.
///
/// [`and_then`]: Option::and_then
///
/// # Examples
///
/// ```
/// let x = Some(2);
/// let y: Option<&str> = None;
/// assert_eq!(x.and(y), None);
///
/// let x: Option<u32> = None;
/// let y = Some("foo");
/// assert_eq!(x.and(y), None);
///
/// let x = Some(2);
/// let y = Some("foo");
/// assert_eq!(x.and(y), Some("foo"));
///
/// let x: Option<u32> = None;
/// let y: Option<&str> = None;
/// assert_eq!(x.and(y), None);
/// ```
pub fn and<U>(self, optb: Option<U>) -> Option<U> {
match self {
Some(_) => optb,
None => None,
}
}
///
/// Returns [`None`] if the option is [`None`], otherwise calls `f` with the
/// wrapped value and returns the result.
///
/// Some languages call this operation flatmap.
///
/// # Examples
///
/// ```
/// fn sq_then_to_string(x: u32) -> Option<String> {
/// x.checked_mul(x).map(|sq| sq.to_string())
/// }
///
/// assert_eq!(Some(2).and_then(sq_then_to_string), Some(4.to_string()));
/// assert_eq!(Some(1_000_000).and_then(sq_then_to_string), None); // overflowed!
/// assert_eq!(None.and_then(sq_then_to_string), None);
/// ```
///
/// Often used to chain fallible operations that may return [`None`].
///
/// ```
/// let arr_2d = [["A0", "A1"], ["B0", "B1"]];
///
/// let item_0_1 = arr_2d.get(0).and_then(|row| row.get(1));
/// assert_eq!(item_0_1, Some(&"A1"));
///
/// let item_2_0 = arr_2d.get(2).and_then(|row| row.get(0));
/// assert_eq!(item_2_0, None);
/// ```
pub fn and_then<U, F>(self, f: F) -> Option<U>
where
F: FnOnce(T) -> Option<U>,
{
match self {
Some(x) => f(x),
None => None,
}
}
///
/// Returns [`None`] if the option is [`None`], otherwise calls `predicate`
/// with the wrapped value and returns:
///
/// - [`Some(t)`] if `predicate` returns `true` (where `t` is the wrapped
/// value), and
/// - [`None`] if `predicate` returns `false`.
///
/// This function works similar to [`Iterator::filter()`]. You can imagine
/// the `Option<T>` being an iterator over one or zero elements. `filter()`
/// lets you decide which elements to keep.
///
/// # Examples
///
/// ```rust
/// fn is_even(n: &i32) -> bool {
/// n % 2 == 0
/// }
///
/// assert_eq!(None.filter(is_even), None);
/// assert_eq!(Some(3).filter(is_even), None);
/// assert_eq!(Some(4).filter(is_even), Some(4));
/// ```
///
/// [`Some(t)`]: Some
pub fn filter<P>(self, predicate: P) -> Self
where
P: FnOnce(&T) -> bool,
{
if let Some(x) = self {
if predicate(&x) {
return Some(x);
}
}
None
}
///
/// Returns the option if it contains a value, otherwise returns `optb`.
///
/// Arguments passed to `or` are eagerly evaluated; if you are passing the
/// result of a function call, it is recommended to use [`or_else`], which is
/// lazily evaluated.
///
/// [`or_else`]: Option::or_else
///
/// # Examples
///
/// ```
/// let x = Some(2);
/// let y = None;
/// assert_eq!(x.or(y), Some(2));
///
/// let x = None;
/// let y = Some(100);
/// assert_eq!(x.or(y), Some(100));
///
/// let x = Some(2);
/// let y = Some(100);
/// assert_eq!(x.or(y), Some(2));
///
/// let x: Option<u32> = None;
/// let y = None;
/// assert_eq!(x.or(y), None);
/// ```
pub fn or(self, optb: Option<T>) -> Option<T> {
match self {
x @ Some(_) => x,
None => optb,
}
}
///
/// Returns the option if it contains a value, otherwise calls `f` and
/// returns the result.
///
/// # Examples
///
/// ```
/// fn nobody() -> Option<&'static str> { None }
/// fn vikings() -> Option<&'static str> { Some("vikings") }
///
/// assert_eq!(Some("barbarians").or_else(vikings), Some("barbarians"));
/// assert_eq!(None.or_else(vikings), Some("vikings"));
/// assert_eq!(None.or_else(nobody), None);
/// ```
pub fn or_else<F>(self, f: F) -> Option<T>
where
F: FnOnce() -> Option<T>,
{
match self {
x @ Some(_) => x,
None => f(),
}
}
///
/// Returns [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns [`None`].
///
/// # Examples
///
/// ```
/// let x = Some(2);
/// let y: Option<u32> = None;
/// assert_eq!(x.xor(y), Some(2));
///
/// let x: Option<u32> = None;
/// let y = Some(2);
/// assert_eq!(x.xor(y), Some(2));
///
/// let x = Some(2);
/// let y = Some(2);
/// assert_eq!(x.xor(y), None);
///
/// let x: Option<u32> = None;
/// let y: Option<u32> = None;
/// assert_eq!(x.xor(y), None);
/// ```
pub fn xor(self, optb: Option<T>) -> Option<T> {
match (self, optb) {
(a @ Some(_), None) => a,
(None, b @ Some(_)) => b,
_ => None,
}
}- Entry-like operations to insert a value and return a reference
///
/// Inserts `value` into the option, then returns a mutable reference to it.
///
/// If the option already contains a value, the old value is dropped.
///
/// See also [`Option::get_or_insert`], which doesn't update the value if
/// the option already contains [`Some`].
///
/// # Example
///
/// ```
/// let mut opt = None;
/// let val = opt.insert(1);
/// assert_eq!(*val, 1);
/// assert_eq!(opt.unwrap(), 1);
/// let val = opt.insert(2);
/// assert_eq!(*val, 2);
/// *val = 3;
/// assert_eq!(opt.unwrap(), 3);
/// ```
pub fn insert(&mut self, value: T) -> &mut T {
*self = Some(value);
unsafe { self.as_mut().unwrap_unchecked() }
}
///
/// Inserts `value` into the option if it is [`None`], then
/// returns a mutable reference to the contained value.
///
/// See also [`Option::insert`], which updates the value even if
/// the option already contains [`Some`].
///
/// # Examples
///
/// ```
/// let mut x = None;
///
/// {
/// let y: &mut u32 = x.get_or_insert(5);
/// assert_eq!(y, &5);
///
/// *y = 7;
/// }
///
/// assert_eq!(x, Some(7));
/// ```
pub fn get_or_insert(&mut self, value: T) -> &mut T {
if let None = *self {
*self = Some(value);
}
unsafe { self.as_mut().unwrap_unchecked() }
}
///
/// Inserts the default value into the option if it is [`None`], then
/// returns a mutable reference to the contained value.
///
/// # Examples
///
/// ```
/// #![feature(option_get_or_insert_default)]
///
/// let mut x = None;
///
/// {
/// let y: &mut u32 = x.get_or_insert_default();
/// assert_eq!(y, &0);
///
/// *y = 7;
/// }
///
/// assert_eq!(x, Some(7));
/// ```
pub fn get_or_insert_default(&mut self) -> &mut T
where
T: Default,
{
self.get_or_insert_with(T::default)
}
///
/// Inserts a value computed from `f` into the option if it is [`None`],
/// then returns a mutable reference to the contained value.
///
/// # Examples
///
/// ```
/// let mut x = None;
///
/// {
/// let y: &mut u32 = x.get_or_insert_with(|| 5);
/// assert_eq!(y, &5);
///
/// *y = 7;
/// }
///
/// assert_eq!(x, Some(7));
/// ```
pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
where
F: FnOnce() -> T,
{
if let None = self {
*self = Some(f());
}
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
// variant in the code above.
unsafe { self.as_mut().unwrap_unchecked() }
}- Misc
///
/// Takes the value out of the option, leaving a [`None`] in its place.
///
/// # Examples
///
/// ```
/// let mut x = Some(2);
/// let y = x.take();
/// assert_eq!(x, None);
/// assert_eq!(y, Some(2));
///
/// let mut x: Option<u32> = None;
/// let y = x.take();
/// assert_eq!(x, None);
/// assert_eq!(y, None);
/// ```
pub const fn take(&mut self) -> Option<T> {
// FIXME replace `mem::replace` by `mem::take` when the latter is const ready
mem::replace(self, None)
}
///
/// Takes the value out of the option, but only if the predicate evaluates to
/// `true` on a mutable reference to the value.
///
/// In other words, replaces `self` with `None` if the predicate returns `true`.
/// This method operates similar to [`Option::take`] but conditional.
///
/// # Examples
///
/// ```
/// let mut x = Some(42);
///
/// let prev = x.take_if(|v| if *v == 42 {
/// *v += 1;
/// false
/// } else {
/// false
/// });
/// assert_eq!(x, Some(43));
/// assert_eq!(prev, None);
///
/// let prev = x.take_if(|v| *v == 43);
/// assert_eq!(x, None);
/// assert_eq!(prev, Some(43));
/// ```
pub fn take_if<P>(&mut self, predicate: P) -> Option<T>
where
P: FnOnce(&mut T) -> bool,
{
if self.as_mut().map_or(false, predicate) { self.take() } else { None }
}
///
/// Replaces the actual value in the option by the value given in parameter,
/// returning the old value if present,
/// leaving a [`Some`] in its place without deinitializing either one.
///
/// # Examples
///
/// ```
/// let mut x = Some(2);
/// let old = x.replace(5);
/// assert_eq!(x, Some(5));
/// assert_eq!(old, Some(2));
///
/// let mut x = None;
/// let old = x.replace(3);
/// assert_eq!(x, Some(3));
/// assert_eq!(old, None);
/// ```
pub const fn replace(&mut self, value: T) -> Option<T> {
mem::replace(self, Some(value))
}
///
/// Zips `self` with another `Option`.
///
/// If `self` is `Some(s)` and `other` is `Some(o)`, this method returns `Some((s, o))`.
/// Otherwise, `None` is returned.
///
/// # Examples
///
/// ```
/// let x = Some(1);
/// let y = Some("hi");
/// let z = None::<u8>;
///
/// assert_eq!(x.zip(y), Some((1, "hi")));
/// assert_eq!(x.zip(z), None);
/// ```
pub fn zip<U>(self, other: Option<U>) -> Option<(T, U)> {
match (self, other) {
(Some(a), Some(b)) => Some((a, b)),
_ => None,
}
}
///
/// Zips `self` and another `Option` with function `f`.
///
/// If `self` is `Some(s)` and `other` is `Some(o)`, this method returns `Some(f(s, o))`.
/// Otherwise, `None` is returned.
///
/// # Examples
///
/// ```
/// #![feature(option_zip)]
///
/// #[derive(Debug, PartialEq)]
/// struct Point {
/// x: f64,
/// y: f64,
/// }
///
/// impl Point {
/// fn new(x: f64, y: f64) -> Self {
/// Self { x, y }
/// }
/// }
///
/// let x = Some(17.5);
/// let y = Some(42.7);
///
/// assert_eq!(x.zip_with(y, Point::new), Some(Point { x: 17.5, y: 42.7 }));
/// assert_eq!(x.zip_with(None, Point::new), None);
/// ```
pub fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
where
F: FnOnce(T, U) -> R,
{
match (self, other) {
(Some(a), Some(b)) => Some(f(a, b)),
_ => None,
}
}Metadata
Metadata
Assignees
Labels
No labels