खोज…
परिचय
Option<T>
प्रकार रुस्ट के नुल्ले प्रकार के बराबर है, इसके साथ आने वाले सभी मुद्दों के बिना। सी जैसी भाषाओं का बहुमत किसी भी चर को null
होने की अनुमति देता है अगर कोई डेटा मौजूद नहीं है, लेकिन Option
प्रकार कार्यात्मक भाषाओं से प्रेरित है जो 'वैकल्पिक' (जैसे हास्केल की Maybe
मोनड) का पक्ष लेते हैं। Option
प्रकारों का उपयोग करने से आपको यह विचार व्यक्त करने की अनुमति मिलेगी कि डेटा हो सकता है या नहीं हो सकता है (चूंकि जंग में अशक्त प्रकार नहीं हैं)।
एक विकल्प मूल्य और पैटर्न मैच बनाना
// The Option type can either contain Some value or None.
fn find(value: i32, slice: &[i32]) -> Option<usize> {
for (index, &element) in slice.iter().enumerate() {
if element == value {
// Return a value (wrapped in Some).
return Some(index);
}
}
// Return no value.
None
}
fn main() {
let array = [1, 2, 3, 4, 5];
// Pattern match against the Option value.
if let Some(index) = find(2, &array) {
// Here, there is a value.
println!("The element 2 is at index {}.", index);
}
// Check if the result is None (no value).
if let None = find(12, &array) {
// Here, there is no value.
println!("The element 12 is not in the array.");
}
// You can also use `is_some` and `is_none` helpers
if find(12, &array).is_none() {
println!("The element 12 is not in the array.");
}
}
एक विकल्प को नष्ट करना
fn main() {
let maybe_cake = Some("Chocolate cake");
let not_cake = None;
// The unwrap method retrieves the value from the Option
// and panics if the value is None
println!("{}", maybe_cake.unwrap());
// The expect method works much like the unwrap method,
// but panics with a custom, user provided message.
println!("{}", not_cake.expect("The cake is a lie."));
// The unwrap_or method can be used to provide a default value in case
// the value contained within the option is None. This example would
// print "Cheesecake".
println!("{}", not_cake.unwrap_or("Cheesecake"));
// The unwrap_or_else method works like the unwrap_or method,
// but allows us to provide a function which will return the
// fallback value. This example would print "Pumpkin Cake".
println!("{}", not_cake.unwrap_or_else(|| { "Pumpkin Cake" }));
// A match statement can be used to safely handle the possibility of none.
match maybe_cake {
Some(cake) => println!("{} was consumed.", cake),
None => println!("There was no cake.")
}
// The if let statement can also be used to destructure an Option.
if let Some(cake) = maybe_cake {
println!("{} was consumed.", cake);
}
}
अपनी सामग्री के स्वामित्व वाले एक विकल्प के संदर्भ को खोलना
एक विकल्प का संदर्भ &Option<T>
unwrapped नहीं किया जा सकता है, तो प्रकार T
copyable नहीं है। इसका समाधान as_ref()
का उपयोग करके विकल्प को &Option<&T>
as_ref()
।
वस्तुओं के स्वामित्व के आधार पर जंगलों को रोकना, जबकि वस्तुओं को उधार लिया जाता है। जब विकल्प स्वयं उधार लिया जाता है ( &Option<T>
), तो इसकी सामग्री भी - अप्रत्यक्ष रूप से - उधार ली जाती है।
#[derive(Debug)]
struct Foo;
fn main() {
let wrapped = Some(Foo);
let wrapped_ref = &wrapped;
println!("{:?}", wrapped_ref.unwrap()); // Error!
}
उधार ली गई सामग्री से बाहर नहीं जा सकते [--explain E0507]
हालांकि, Option<T>
की सामग्री के लिए एक संदर्भ बनाना संभव है। विकल्प का as_ref()
विधि &T
लिए एक विकल्प देता है, जिसे स्वामित्व के हस्तांतरण के बिना as_ref()
किया जा सकता है:
println!("{:?}", wrapped_ref.as_ref().unwrap());
मानचित्र और। के साथ विकल्प का उपयोग करना
map
ऑपरेशन एक उपयोगी उपकरण है जब सरणियों और वैक्टर के साथ काम करते हैं, लेकिन इसका उपयोग कार्यात्मक तरीके से Option
मानों से निपटने के लिए भी किया जा सकता है।
fn main() {
// We start with an Option value (Option<i32> in this case).
let some_number = Some(9);
// Let's do some consecutive calculations with our number.
// The crucial point here is that we don't have to unwrap
// the content of our Option type - instead, we're just
// transforming its content. The result of the whole operation
// will still be an Option<i32>. If the initial value of
// 'some_number' was 'None' instead of 9, then the result
// would also be 'None'.
let another_number = some_number
.map(|n| n - 1) // => Some(8)
.map(|n| n * n) // => Some(64)
.and_then(|n| divide(n, 4)); // => Some(16)
// In the last line above, we're doing a division using a helper
// function (definition: see bottom).
// 'and_then' is very similar to 'map', but allows us to pass a
// function which returns an Option type itself. To ensure that we
// don't end up with Option<Option<i32>>, 'and_then' flattens the
// result (in other languages, 'and_then' is also known as 'flatmap').
println!("{}", to_message(another_number));
// => "16 is definitely a number!"
// For the sake of completeness, let's check the result when
// dividing by zero.
let final_number = another_number
.and_then(|n| divide(n, 0)); // => None
println!("{}", to_message(final_number));
// => "None!"
}
// Just a helper function for integer division. In case
// the divisor is zero, we'll get 'None' as result.
fn divide(number: i32, divisor: i32) -> Option<i32> {
if divisor != 0 { Some(number/divisor) } else { None }
}
// Creates a message that tells us whether our
// Option<i32> contains a number or not. There are other
// ways to achieve the same result, but let's just use
// map again!
fn to_message(number: Option<i32>) -> String {
number
.map(|n| format!("{} is definitely a number!", n)) // => Some("...")
.unwrap_or("None!".to_string()) // => "..."
}
Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow