Option¶
See the original Rust documentation here.
patina.option |
Optional values. |
Option |
The Option type. |
Some(value) |
|
None_ |
Optional values.
Type Option represents an optional value: every Option is either
Some and contains a value, or None_, and does not.
Option types are very common in Rust code, as they have a number of uses:
- Initial values
- Return values for functions that are not defined over their entire input range (partial functions)
- Return value for otherwise reporting simple errors, where
None_is returned on error - Optional struct fields
- Struct fields that can be loaned or “taken”
- Optional function arguments
- Nullable pointers
- Swapping things out of difficult situations
Options are commonly paired with pattern matching to query the presence of a
value and take action, always accounting for the None_ case.
>>> def divide(numerator: float, denominator: float) -> Option[float]:
... if denominator == 0.0:
... return None_()
... return Some(numerator / denominator)
...
>>> result = divide(2.0, 3.0)
>>>
>>> if result.is_some():
... print(f"Result: {result.unwrap()}")
... else:
... print(f"Cannot divide by 0")
...
Result: 0.6666666666666666
Examples¶
Basic pattern matching on Option:
>>> msg = Some("howdy")
>>>
>>> if msg.is_some():
... print(msg.unwrap())
...
howdy
>>> unwrapped_msg = msg.unwrap_or("default message")
>>> unwrapped_msg
'howdy'
Initialize a result to None_ before a loop:
>>> from dataclasses import dataclass
>>>
>>> @dataclass
... class Kingdom:
... size: int
... name: str
...
>>> class PlantKingdom(Kingdom): pass
...
>>> class AnimalKingdom(Kingdom): pass
...
>>> all_the_big_things = [
... PlantKingdom(250, "redwood"),
... PlantKingdom(230, "noble fir"),
... PlantKingdom(229, "sugar pine"),
... AnimalKingdom(25, "blue whale"),
... AnimalKingdom(19, "fin whale"),
... AnimalKingdom(15, "north pacific right whale"),
... ]
>>>
>>> # We're going to search for the name of the biggest animal, but to start
>>> # with we've just got `None_`
>>> name_of_biggest_animal: Option[str] = None_()
>>> size_of_biggest_animal = 0
>>> for big_thing in all_the_big_things:
... if isinstance(big_thing, AnimalKingdom) \
... and big_thing.size > size_of_biggest_animal:
... size_of_biggest_animal = big_thing.size
... name_of_biggest_animal = Some(big_thing.name)
...
>>> if name_of_biggest_animal.is_some():
... print(f"the biggest animal is {name_of_biggest_animal.unwrap()}")
... else:
... print("there are no animals :(")
...
the biggest animal is blue whale
The Option Type¶
-
class
patina.option.Option¶ The
Optiontype. See themodule-level documentationfor more.-
__bool__() → bool¶ Returns
Trueif the option is aSomevalue, elseFalse.>>> x: Option[int] = Some(0) >>> True if x else False True >>> y: Option[int] = None_() >>> True if y else False False
-
is_some() → bool¶ Returns
Trueif the option is aSomevalue.>>> x: Option[int] = Some(2) >>> x.is_some() True >>> x: Option[int] = None_() >>> x.is_some() False
-
is_none() → bool¶ Returns
Trueif the option is aNone_value.>>> x: Option[int] = Some(2) >>> x.is_none() False >>> x: Option[int] = None_() >>> x.is_none() True
-
expect(msg: str) → T¶ Returns the contained
Somevalue.Raises: AssertionError – Raised if the value is a None_, with a custom message provided bymsg.>>> x = Some("value") >>> x.expect("fruits are healthy") 'value' >>> x: Option[str] = None_() >>> x.expect("fruits are healthy") Traceback (most recent call last): ... AssertionError: fruits are healthy
-
unwrap() → T¶ Returns the contained
Somevalue.Because this function may panic, its use is generally discouraged. Instead, prefer to use pattern matching and handle the
None_case explicitly, or callunwrap_or()orunwrap_or_else().Raises: AssertionError – Raised if the self value is None_.>>> x = Some("air") >>> x.unwrap() 'air' >>> x: Option[str] = None_() >>> x.unwrap() Traceback (most recent call last): ... AssertionError: called `Option.unwrap` on a `None_` value
-
unwrap_or(default: T) → T¶ Returns the contained
Somevalue or a provided default.Arguments passed to
unwrap_orare eagerly evaluated; if you are passing the result of a function call, it is recommended to useunwrap_or_else(), which is lazily evaluated.>>> Some("car").unwrap_or("bike") 'car' >>> None_[str]().unwrap_or("bike") 'bike'
-
unwrap_or_else(f: Callable[[], T]) → T¶ Returns the contained
Somevalue or computes it from a closure.>>> k = 10 >>> Some(4).unwrap_or_else(lambda: 2 * k) 4 >>> None_[int]().unwrap_or_else(lambda: 2 * k) 20
-
map(f: Callable[[T], U]) → patina.option.Option[~U][U]¶ Maps an
Option[T]toOption[U]by applying a function to a contained value.Converting an
Option[str]into anOption[int]:>>> maybe_some_string = Some("Hello, World!") >>> maybe_some_len = maybe_some_string.map(len) >>> maybe_some_len Some(13)
-
map_or(default: U, f: Callable[[T], U]) → U¶ Applies a function to the contained value (if any), or returns the provided default (if not).
Arguments passed to
map_orare eagerly evaluated; if you are passing the result of a function call, it is recommended to usemap_or_else(), which is lazily evaluated.>>> x = Some("foo") >>> x.map_or(42, len) 3 >>> x: Option[str] = None_() >>> x.map_or(42, len) 42
-
map_or_else(default: Callable[[], U], f: Callable[[T], U]) → U¶ Applies a function to the contained value (if any), or computes a default (if not).
>>> k = 21 >>> >>> x = Some("foo") >>> x.map_or_else(lambda: 2 * k, len) 3 >>> x: Option[str] = None_() >>> x.map_or_else(lambda: 2 * k, len) 42
-
ok_or(err: E) → patina.result.Result[~T, ~E][T, E]¶ Transforms the
Option[T]into aResult[T, E], mappingSome(v)toOk(v)andNone_toErr(err).Arguments passed to
ok_orare eagerly evaluated; if you are passing the result of a function call, it is recommended to useok_or_else(), which is lazily evaluated.>>> x = Some("foo") >>> x.ok_or(0) Ok('foo') >>> x: Option[str] = None_() >>> x.ok_or(0) Err(0)
-
ok_or_else(err: Callable[[], E]) → patina.result.Result[~T, ~E][T, E]¶ Transforms the
Option[T]into aResult[T, E], mappingSome(v)toOk(v)andNone_toErr(err()).>>> x = Some("foo") >>> x.ok_or_else(lambda: 0) Ok('foo') >>> x: Option[str] = None_() >>> x.ok_or_else(lambda: 0) Err(0)
-
iter() → Iterator[T]¶ Returns an iterator over the possibly contained value.
>>> x = Some(4) >>> next(x.iter()) 4 >>> x: Option[int] = None_() >>> next(x.iter()) Traceback (most recent call last): ... StopIteration
-
__iter__()¶ Returns an iterator over the possibly contained value.
>>> x = Some(4) >>> next(iter(x)) 4 >>> x: Option[int] = None_() >>> next(iter(x)) Traceback (most recent call last): ... StopIteration
-
and_(optb: patina.option.Option[~U][U]) → patina.option.Option[~U][U]¶ Returns
None_if the option isNone_, otherwise returnsoptb.>>> x = Some(2) >>> y: Option[str] = None_() >>> x.and_(y) None_ >>> x: Option[int] = None_() >>> y = Some("foo") >>> x.and_(y) None_ >>> x = Some(2) >>> y = Some("foo") >>> x.and_(y) Some('foo') >>> x: Option[int] = None_() >>> y: Option[str] = None_() >>> x.and_(y) None_
-
and_then(f: Callable[[T], Option[U]]) → patina.option.Option[~U][U]¶ Returns
None_if the option isNone_, otherwise callsfwith the wrapped value and returns the result.Some languages call this operation flatmap.
>>> def sq(x: int) -> Option[int]: return Some(x * x) ... >>> def nope(_: int) -> Option[int]: return None_() ... >>> Some(2).and_then(sq).and_then(sq) Some(16) >>> Some(2).and_then(sq).and_then(nope) None_ >>> Some(2).and_then(nope).and_then(sq) None_ >>> None_[int]().and_then(sq).and_then(sq) None_
-
filter(predicate: Callable[[T], bool]) → patina.option.Option[~T][T]¶ Returns
None_if the option isNone_, otherwise callspredicatewith the wrapped value and returns:Some(t)ifpredicatereturnsTrue(wheretis the wrapped value, andNone_ifpredicatereturnsFalse.
This function works similar to
filter(). You can imagine theOption[T]being an iterator over one or zero elements.filter()lets you decide which elements to keep.>>> def is_even(n: int) -> bool: return n % 2 == 0 ... >>> None_[int]().filter(is_even) None_ >>> Some(3).filter(is_even) None_ >>> Some(4).filter(is_even) Some(4)
-
or_(optb: patina.option.Option[~T][T]) → patina.option.Option[~T][T]¶ Returns the option if it contains a value, otherwise returns
optb.Arguments passed to
orare eagerly evaluated; if you are passing the result of a function call, it is recommended to useor_else(), which is lazily evaluated.>>> x = Some(2) >>> y: Option[int] = None_() >>> x.or_(y) Some(2) >>> x: Option[int] = None_() >>> y = Some(100) >>> x.or_(y) Some(100) >>> x = Some(2) >>> y = Some(100) >>> x.or_(y) Some(2) >>> x: Option[int] = None_() >>> y: Option[int] = None_() >>> x.or_(y) None_
-
or_else(f: Callable[[], Option[T]]) → patina.option.Option[~T][T]¶ Returns the option if it contains a value, otherwise calls
fand returns the result.>>> def nobody() -> Option[str]: return None_() ... >>> def vikings() -> Option[str]: return Some("vikings") ... >>> Some("barbarians").or_else(vikings) Some('barbarians') >>> None_[str]().or_else(vikings) Some('vikings') >>> None_[str]().or_else(nobody) None_
-
xor(optb: patina.option.Option[~T][T]) → patina.option.Option[~T][T]¶ Returns
Someif exactly one ofself,optbisSome, otherwise returnsNone_.>>> x = Some(2) >>> y: Option[int] = None_() >>> x.xor(y) Some(2) >>> x: Option[int] = None_() >>> y = Some(2) >>> x.xor(y) Some(2) >>> x = Some(2) >>> y = Some(2) >>> x.xor(y) None_ >>> x: Option[int] = None_() >>> y: Option[int] = None_() >>> x.xor(y) None_
-
get_or_insert(v: T) → patina.ref.Ref[~T][T]¶ Inserts
vinto the option if it isNone_, then returns a reference to the contained value.>>> x: Option[int] = None_() >>> y = x.get_or_insert(5) >>> y.get() 5 >>> y.set(7) >>> x Some(7)
-
get_or_insert_with(f: Callable[[], T]) → patina.ref.Ref[~T][T]¶ Inserts a value computed from
finto the option if it isNone_, then returns a reference to the contained value.>>> x: Option[int] = None_() >>> y = x.get_or_insert_with(lambda: 5) >>> y.get() 5 >>> y.set(7) >>> x Some(7)
-
take() → patina.option.Option[~T][T]¶ Takes the value out of the option, leaving a
None_in its place.>>> x = Some(2) >>> y = x.take() >>> x None_ >>> y Some(2) >>> x: Option[int] = None_() >>> y = x.take() >>> x None_ >>> y None_
-
replace(value: T) → patina.option.Option[~T][T]¶ Replaces the actual value in the option by the value given in parameter, returning the old value if present, leaving a
Somein its place without deinitializing either one.>>> x = Some(2) >>> old = x.replace(5) >>> x Some(5) >>> old Some(2) >>> x = None_[int]() >>> old = x.replace(3) >>> x Some(3) >>> old None_
-
zip(other: patina.option.Option[~U][U]) → patina.option.Option[typing.Tuple[~T, ~U]][Tuple[T, U]]¶ Zips
selfwith anotherOption.If
selfisSome(s)andotherisSome(o), this method returnsSome((s, o)). Otherwise,None_is returned.>>> x = Some(1) >>> y = Some("hi") >>> z = None_[int]() >>> x.zip(y) Some((1, 'hi')) >>> x.zip(z) None_
-
classmethod
from_optional(opt: Optional[T]) → patina.option.Option[~T][T]¶ Get an
Option[T]from anOptional[T].If
optisNone, returnNone_(), otherwise returnSome(obj). This does not come from Rust’s API.>>> from typing import Optional >>> x: Optional[int] = None >>> Option.from_optional(x) None_ >>> x: Optional[int] = 42 >>> Option.from_optional(x) Some(42)
-
into_optional() → Optional[T]¶ Get a typing.Optional[T] from an
Option[T].Returns
NoneifselfisNone_(), otherwise returns the contained value.>>> from typing import Optional >>> x: Optional[int] = None >>> opt = Option.from_optional(x) >>> opt None_ >>> opt.into_optional() >>> assert x is opt.into_optional() >>> >>> x = 3 >>> opt = Option.from_optional(x) >>> opt Some(3) >>> opt.into_optional() 3 >>> assert x is opt.into_optional()
-
__weakref__¶ list of weak references to the object (if defined)
-