మాడ్యూల్ పాఠాలు (2/2)
స్మార్ట్ పాయింటర్లు: బాక్స్ మరియు Rc
స్మార్ట్ పాయింటర్ అనేది పాయింటర్ వలె ప్రవర్తించే డేటా నిర్మాణం, కానీ మెటాడేటా మరియు అదనపు సామర్థ్యాలను కలిగి ఉంటుంది (రిఫరెన్స్ లెక్కింపు లేదా ఆటోమేటిక్ మెమరీ నిర్వహణ వంటివి).
రస్ట్లో, సాధారణ సూచనలు (& వంటివి) డేటాను మాత్రమే తీసుకుంటాయి. మరోవైపు, స్మార్ట్ పాయింటర్లు తరచుగా వారు సూచించే డేటాను కలిగి ఉంటాయి. సాధారణ ఉదాహరణలలో String మరియు Vec<T> ఉన్నాయి, కానీ ప్రామాణిక లైబ్రరీ ఇతర ప్రత్యేకమైన వాటిని అందిస్తుంది.
కుప్ప కేటాయింపు కోసం బాక్స్<T>
సరళమైన స్మార్ట్ పాయింటర్ Box<T>, ఇది స్టాక్లో కాకుండా కుప్పలో డేటాను నిల్వ చేస్తుంది. కుప్ప-కేటాయించిన డేటాకు పాయింటర్ మాత్రమే స్టాక్లో ఉంటుంది.
ఇది ప్రధానంగా క్రింది సందర్భాలలో ఉపయోగించబడుతుంది:
- మీరు కంపైల్ సమయంలో (పునరావృత రకం వంటి) పరిమాణం తెలియలేని రకాన్ని కలిగి ఉన్నప్పుడు మరియు మీరు ఖచ్చితమైన పరిమాణం అవసరమయ్యే సందర్భంలో ఆ రకం విలువను ఉపయోగించాలనుకున్నప్పుడు.
- మీరు పెద్ద మొత్తంలో డేటాను కాపీ చేయకుండా యాజమాన్యాన్ని బదిలీ చేయాలనుకున్నప్పుడు.
ఆధార ఉదాహరణ:
fn main() {
let b = Box::new(5); // allocates the value 5 on the heap
println!("b = {}", *b); // dereferences with * to read the value
}పునరావృత రకాలు మరియు నష్టాల జాబితాలు
పునరావృత రకం అనేది దాని నిర్వచనంలో భాగంగా దాని విలువను కలిగి ఉండే రకం. రస్ట్ కంపైల్ సమయంలో ఒక రకం యొక్క ఖచ్చితమైన పరిమాణాన్ని తెలుసుకోవాలి. పునరావృత రకం యొక్క డెప్త్ అనంతం కావచ్చు కాబట్టి, మీరు బాక్స్ను ఉపయోగించనంత వరకు కంపైలర్ లోపాన్ని సృష్టిస్తుంది (దీనికి నిర్ణీత పరిమాణం ఉంటుంది, ఎందుకంటే ఇది పాయింటర్గా ఉంటుంది):
enum List {
Cons(i32, Box<List>),
Nil,
}Rc<T>: సూచన లెక్కింపు
ఒకే విలువ బహుళ యజమానులను కలిగి ఉండే సందర్భాలు ఉన్నాయి. Rc<T> (రిఫరెన్స్ కౌంట్ చేయబడింది) స్మార్ట్ పాయింటర్ విలువ ఇప్పటికీ ఉపయోగంలో ఉందో లేదో తెలుసుకోవడానికి విలువకు సంబంధించిన సూచనల సంఖ్యను ట్రాక్ చేస్తుంది. గణన సున్నాకి పడిపోతే, వనరు సురక్షితంగా డీలాకేట్ చేయబడుతుంది.
[!గమనిక]
Rc<T>** సింగిల్-థ్రెడ్ దృశ్యాలకు మాత్రమే సరిపోతుంది**. బహుళ-థ్రెడ్ (ఏకకాలిక) దృశ్యాల కోసం, మీరు తప్పనిసరిగాArc<T>(అటామిక్ రిఫరెన్స్ కౌంట్ చేయబడింది)ని ఉపయోగించాలి.
use std::rc::Rc;
fn main() {
let a = Rc::new(5);
let b = Rc::clone(&a); // increments the reference count to 2
println!("References: {}", Rc::strong_count(&a));
}మీరే ప్రయత్నించండి
వ్యాయామం 1: పెట్టెతో కుప్ప కేటాయింపు
Box::newని ఉపయోగించి కుప్పపై పూర్ణాంకం విలువ 42ను కేటాయించండి మరియు దానిని val అనే వేరియబుల్కు కేటాయించండి. తర్వాత, బాక్స్లో నిల్వ చేయబడిన విలువను * ఆపరేటర్తో స్పష్టంగా డీఫరెన్స్ చేయడం ద్వారా ప్రింట్ చేయండి.
సూచనను చూపించు
విలువను హీప్లో నిల్వ చేయడానికి `లెట్ వాల్ = బాక్స్:: న్యూ(42);` ఉపయోగించండి మరియు `ప్రింట్ల్న్!` లోపల `*వాల్`తో డిఫరెన్స్ చేయండి.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
వ్యాయామం 2: పునరావృత డేటా నిర్మాణం (కాన్స్ జాబితా)
రెండు వేరియంట్లను కలిగి ఉన్న రికర్సివ్ ఎన్యూమ్ను నిర్వచించండి: టుపుల్ను చుట్టే కాన్స్ (i32, బాక్స్ <జాబితా>), మరియు జాబితా ముగింపును సూచించే నిల్. ప్రధాన ఫంక్షన్లో, ఎలిమెంట్ 1 తర్వాత Nil ఉన్న లింక్డ్ లిస్ట్ను ఇన్స్టాంటియేట్ చేయండి.
సూచనను చూపించు
enum `enum List { Cons(i32, Box<List>), Nil }`గా ప్రకటించబడింది.`జాబితా::Cons(1, Box::new(List::Nil))`తో జాబితాను తక్షణం చేయండి.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
వ్యాయామం 3: Rcతో యాజమాన్యాన్ని పంచుకోవడం
ఒక వేరియబుల్లో 100 విలువను కలిగి ఉన్న భాగస్వామ్య పూర్ణాంకాన్ని సృష్టించడానికి std::rc::Rc ఉపయోగించండి. Rc::cloneని ఉపయోగించి సూచనను వేరియబుల్ bలోకి క్లోన్ చేయండి. చివరగా, Rc::strong_count ఫంక్షన్ని ఉపయోగించి సక్రియ సూచనల గణనను ప్రింట్ చేయండి.
సూచనను చూపించు
`Rc::new(100)`తో విలువను సృష్టించండి. `Rc::clone(&a)`తో క్లోన్ చేయండి మరియు యజమాని గణనను`Rc::strong_count(&a)`తో ప్రదర్శించండి.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది