Οι γλώσσες προγραμματισμού διαφέρουν ως προς τον τρόπο με τον οποίο χειρίζονται τη μνήμη και επιβάλλουν κανόνες διαχείρισης μνήμης. Η Go και η Python χρησιμοποιούν συλλέκτες σκουπιδιών, ώστε οι προγραμματιστές να μπορούν να επικεντρωθούν στη σύνταξη κώδικα. Η C και η C++ δίνουν στους προγραμματιστές την ευθύνη για τη διαχείριση της μνήμης σε χαμηλότερο επίπεδο.
Η Rust αντιμετωπίζει τη διαχείριση της μνήμης διαφορετικά, χρησιμοποιώντας έννοιες που ονομάζει ιδιοκτησία και δανεισμό. Χρησιμοποιεί έναν «ελεγκτή δανεισμού» για να επιβάλει αποτελεσματικά την ασφάλεια της μνήμης.
Τι είναι η ιδιοκτησία;
Η ιδιοκτησία είναι ένα χαρακτηριστικό και η σύμβαση του Rust που συμβάλλει στη διασφάλιση της ασφάλειας της μνήμης των προγραμμάτων χωρίς συλλέκτη σκουπιδιών. Είναι ένας άλλος τρόπος αντιμετώπισης το πρόβλημα των διαρροών μνήμης στον κωδικό σας.
Ο μεταγλωττιστής Rust ελέγχει εάν ένα πρόγραμμα υπακούει στους κανόνες ιδιοκτησίας κατά τη στιγμή της μεταγλώττισης. Εάν το πρόγραμμα ακολουθεί αυτούς τους κανόνες, μπορεί να εκτελεστεί. Εάν δεν το κάνει, ο μεταγλωττιστής αρνείται να δημιουργήσει ένα εκτελέσιμο αρχείο.
Το Rust επαληθεύει τους κανόνες ιδιοκτησίας χρησιμοποιώντας το δάνειο πούλι. Ο έλεγχος δανεισμού επαληθεύει το μοντέλο ιδιοκτησίας και αποφασίζει εάν μια τιμή στη μνήμη (στοίβα ή στοίβα) είναι εκτός πεδίου εφαρμογής ή όχι. Εάν μια τιμή είναι εκτός του πεδίου εφαρμογής της, δεν είναι προσβάσιμη σε άλλα μέρη του προγράμματος, εκτός εάν είναι δανεισμένη.
Οι κανόνες ιδιοκτησίας
Στο Rust, κάθε μεταβλητή κατέχει την τιμή με την οποία έχει αρχικοποιηθεί και μπορεί να υπάρχει μόνο ένας κάτοχος. Μόλις ο κάτοχος είναι εκτός πεδίου εφαρμογής, η τιμή απορρίπτεται. Είναι σημαντικό να κατανοήσετε τις λεπτομέρειες των κανόνων ιδιοκτησίας.
Ο πρώτος κανόνας ιδιοκτησίας είναι ότι κάθε μεταβλητή κατέχει την αρχική τιμή της.
αφήνω ιδιοκτήτης = Σειρά::Από τη μία");
ο ιδιοκτήτης Η παραπάνω μεταβλητή κατέχει τη συμβολοσειρά ένας και, σε αντίθεση με γλώσσες όπως η Python και η Go, αυτή η τιμή θα απορριφθεί κατά την αλλαγή της μεταβλητής.
Ο δεύτερος κανόνας ιδιοκτησίας είναι ότι δύο μεταβλητές δεν μπορούν να δείχνουν την ίδια θέση μνήμης. κάθε αξία μπορεί να έχει μόνο έναν ιδιοκτήτη.
αφήνω new_owner = ιδιοκτήτης;
ο νέος ιδιοκτήτης μεταβλητή κατέχει πλέον την τιμή που είναι αποθηκευμένη στη θέση μνήμης του ιδιοκτήτης μεταβλητός. Εάν προσπαθήσετε να χρησιμοποιήσετε το ιδιοκτήτης μεταβλητή, ο μεταγλωττιστής θα πανικοβληθεί και θα αρνηθεί να δημιουργήσει ένα εκτελέσιμο αρχείο.
Στις περισσότερες γλώσσες που χρησιμοποιούν συλλέκτες σκουπιδιών, δύο μεταβλητές μπορούν να δείχνουν την ίδια θέση μνήμης. Ακολουθεί ένα παράδειγμα ισοδύναμου κώδικα JavaScript:
αφήνω ιδιοκτήτης = "ιδιοκτήτης";
αφήνω new_owner = ιδιοκτήτης;
κονσόλα.log (new_owner);
Η εκτέλεση του κώδικα JavaScript παραπάνω λειτουργεί χωρίς σφάλματα και αν κάνετε το ίδιο στο Go ή στην Python, το πρόγραμμά σας θα λειτουργήσει επίσης χωρίς σφάλματα.
Ο τρίτος κανόνας ιδιοκτησίας είναι ότι όταν μια μεταβλητή είναι εκτός του δηλωμένου πεδίου εφαρμογής, η τιμή πέφτει και η μνήμη εκχωρείται.
// μια μεταβλητή σε ξεχωριστό πεδίο
{
αφήνω παράδειγμα = Σειρά::from("Εδώ είναι ένα νέο πεδίο εφαρμογής");
}
Τυπώνω!("{}", παράδειγμα)
Δεν μπορείτε να έχετε πρόσβαση στο παράδειγμα μεταβλητή εκτός του πεδίου εφαρμογής της· Προσπαθώντας να το κάνετε αυτό θα προκαλέσει πανικό στον μεταγλωττιστή.
Ιδιοκτησία σε Λειτουργίες
Όταν μεταβιβάζετε μια τιμή σε μια συνάρτηση ως όρισμα, η συνάρτηση μπορεί να έχει πρόσβαση σε αυτήν τη μεταβλητή, παρόλο που δεν είχε δηλωθεί στο εύρος της:
στεκτυπωτής(αξία: Σειρά) -> Σειρά {
ΕΠΙΣΤΡΟΦΗ αξία
}στκύριος() {
αφήνω x = Σειρά::from("Εκτυπώνει μια τιμή"); Το // x κατέχει την τιμή συμβολοσειράς
// η ιδιοκτησία μεταφέρεται στη συνάρτηση εκτυπωτή εδώ
Τυπώνω!("{} Ο Αποτέλεσμα του Printing X είναι ότι -:", εκτυπωτής (x));
}
Η συνάρτηση μπορεί να έχει πρόσβαση σε αυτήν τη μεταβλητή επειδή η Rust μεταφέρει την ιδιοκτησία της στη συνάρτηση κατά το χρόνο μεταγλώττισης.
Ίσως πιστεύετε ότι είναι ακόμα δυνατό να χρησιμοποιήσετε τη μεταβλητή αργότερα στο αρχικό της πεδίο:
στεκτυπωτής(αξία: Σειρά) -> Σειρά {
ΕΠΙΣΤΡΟΦΗ αξία
}στκύριος() {
αφήνω x = Σειρά::from("Εκτυπώνει μια τιμή");
Τυπώνω!("{} Ο Αποτέλεσμα του Εκτύπωση x είναι ότι -:", εκτυπωτής (x));
// Προσπάθεια χρήσης της μεταβλητής μετά τη μεταβίβαση της ιδιοκτησίας της τιμής της
println!("{} δεν πρέπει να είναι προσβάσιμο", x)
}
Αλλά αν δοκιμάσετε αυτό, ο μεταγλωττιστής θα πανικοβληθεί και θα αρνηθεί να δημιουργήσει ένα εκτελέσιμο:
Η Rust δίνει προτεραιότητα στην επαναχρησιμοποίηση κώδικα
Η επαναχρησιμοποίηση κώδικα είναι μια ουσιαστική πρακτική, αλλά για να εξασκήσετε την επαναχρησιμοποίηση κώδικα πρέπει να κατανοήσετε τους κανόνες ιδιοκτησίας του Rust.
Η Rust είναι μια πολύ ευέλικτη γλώσσα προγραμματισμού. Παρέχει έννοιες όπως δανεισμός, μετακίνηση, αντιγραφή και κλωνοποίηση ιδιοκτησίας για μεταβλητή επαναχρησιμοποίηση.