Rust
स्वामित्व
खोज…
परिचय
वाक्य - विन्यास
- Let x: & T = ... // x एक अपरिवर्तनीय संदर्भ है
- Let x: & mut T = ... // x एक अनन्य, परिवर्तनशील संदर्भ है
- let _ = & mut फू; // उधार फू परस्पर (यानी, विशेष रूप से)
- let _ = & foo; // उधार फू फू अपरिवर्तनीय
- चलो _ = फू; // चाल फू (स्वामित्व की आवश्यकता है)
टिप्पणियों
- जंग के पुराने संस्करणों में (1.0 से पहले; मई 2015), एक स्वामित्व वाले चर का एक प्रकार था
~
साथ शुरू। आप इसे बहुत पुराने उदाहरणों में देख सकते हैं।
स्वामित्व और उधार
रस्ट के सभी मूल्यों का एक मालिक है। मालिक उस मूल्य को छोड़ने के लिए जिम्मेदार होता है जब वह दायरे से बाहर हो जाता है, और केवल वही होता है जो मूल्य के स्वामित्व को स्थानांतरित कर सकता है। मूल्य का मालिक उस मूल्य के अन्य टुकड़ों को उधार देकर उसे संदर्भ दे सकता है। किसी भी समय, किसी भी मूल्य के अपरिवर्तनीय संदर्भ हो सकते हैं:
let owned = String::from("hello");
// since we own the value, we may let other variables borrow it
let immutable_borrow1 = &owned;
// as all current borrows are immutable, we can allow many of them
let immutable_borrow2 = &owned;
// in fact, if we have an immutable reference, we are also free to
// duplicate that reference, since we maintain the invariant that
// there are only immutable references
let immutable_borrow3 = &*immutable_borrow2;
या इसका एक एकल परिवर्तनशील संदर्भ ( ERROR
एक संकलन-समय त्रुटि बताता है):
// for us to borrow a value mutably, it must be mutable
let mut owned = String::from("hello");
// we can borrow owned mutably
let mutable_borrow = &mut owned;
// but note that we cannot borrow owned *again*
let mutable_borrow2 = &mut owned; // ERROR, already borrowed
// nor can we cannot borrow owned immutably
// since a mutable borrow is exclusive.
let immutable_borrow = &owned; // ERROR, already borrowed
यदि किसी मान के लिए बकाया संदर्भ (या तो परस्पर या अपरिवर्तनीय) हैं, तो उस मूल्य को स्थानांतरित नहीं किया जा सकता है (यानी, इसका स्वामित्व दूर दिया गया है)। हमें यह सुनिश्चित करना होगा कि मूल्य को स्थानांतरित करने के लिए सभी संदर्भों को पहले गिरा दिया जाए:
let foo = owned; // ERROR, outstanding references to owned
let owned = String::from("hello");
{
let borrow = &owned;
// ...
} // the scope ends the borrow
let foo = owned; // OK, owned and not borrowed
उधार और जीवनदान
जंग में सभी मूल्यों का जीवनकाल होता है । एक मूल्य का जीवनकाल मूल्य से कोड के खंड को फैलाया जाता है, जहां इसे स्थानांतरित किया जाता है, या युक्त गुंजाइश का अंत होता है
{
let x = String::from("hello"); // +
// ... :
let y = String::from("hello"); // + |
// ... : :
foo(x) // x is moved | = x's lifetime
// ... :
} // = y's lifetime
जब भी आप एक मूल्य उधार लेते हैं, तो परिणामी संदर्भ में एक जीवनकाल होता है जो उधार लिया जा रहा मूल्य के जीवनकाल से जुड़ा होता है:
{
let x = String::from("hello");
let y = String::from("world");
// when we borrow y here, the lifetime of the reference
// stored in foo is equal to the lifetime of y
// (i.e., between let y = above, to the end of the scope below)
let foo = &y;
// similarly, this reference to x is bound to the lifetime
// of x --- bar cannot, for example, spawn a thread that uses
// the reference beyond where x is moved below.
bar(&x);
}
स्वामित्व और फ़ंक्शन कॉल
कार्य लिखते समय स्वामित्व के आसपास के अधिकांश प्रश्न सामने आते हैं। जब आप किसी फ़ंक्शन के तर्कों के प्रकारों को निर्दिष्ट करते हैं, तो आप यह चुन सकते हैं कि उस मान को कैसे पास किया जाता है। यदि आपको केवल रीड-ओनली एक्सेस की आवश्यकता है, तो आप एक अपरिवर्तनीय संदर्भ ले सकते हैं:
fn foo(x: &String) {
// foo is only authorized to read x's contents, and to create
// additional immutable references to it if it so desires.
let y = *x; // ERROR, cannot move when not owned
x.push_str("foo"); // ERROR, cannot mutate with immutable reference
println!("{}", x.len()); // reading OK
foo(x); // forwarding reference OK
}
अगर foo
को तर्क को संशोधित करने की आवश्यकता है, तो इसे एक विशेष, परिवर्तनशील संदर्भ लेना चाहिए:
fn foo(x: &mut String) {
// foo is still not responsible for dropping x before returning,
// nor is it allowed to. however, foo may modify the String.
let x2 = *x; // ERROR, cannot move when not owned
x.push_str("foo"); // mutating OK
drop(*x); // ERROR, cannot drop value when not owned
println!("{}", x.len()); // reading OK
}
यदि आप या तो &
&mut
निर्दिष्ट नहीं करते हैं, तो आप कह रहे हैं कि फ़ंक्शन किसी तर्क का स्वामित्व लेगा। इसका मतलब है कि foo
अब x
को छोड़ने के लिए भी जिम्मेदार है।
fn foo(x: String) {
// foo may do whatever it wishes with x, since no-one else has
// access to it. once the function terminates, x will be dropped,
// unless it is moved away when calling another function.
let mut x2 = x; // moving OK
x2.push_str("foo"); // mutating OK
let _ = &mut x2; // mutable borrow OK
let _ = &x2; // immutable borrow OK (note that &mut above is dropped)
println!("{}", x2.len()); // reading OK
drop(x2); // dropping OK
}
स्वामित्व और प्रतिलिपि विशेषता
कुछ रस्ट प्रकार Copy
विशेषता को लागू करते हैं। Copy
प्रकार जो प्रश्न में मान के स्वामी के बिना स्थानांतरित किए जा सकते हैं। ऐसा इसलिए है क्योंकि मूल्य की सामग्री को एक नए, समान मूल्य का उत्पादन करने के लिए बस बाइट के लिए बाइट में कॉपी किया जा सकता है। रस्ट ( bool
, usize
, f64
, आदि) में अधिकांश प्राइमिटिव Copy
।
let x: isize = 42;
let xr = &x;
let y = *xr; // OK, because isize is Copy
// both x and y are owned here
विशेष रूप से, Vec
और String
Copy
नहीं हैं:
let x = Vec::new();
let xr = &x;
let y = *xr; // ERROR, cannot move out of borrowed content