Ποια χρονιά εμφανίστηκε η γλώσσα προγραμματισμού rust; Από πού να ξεκινήσετε · Γλώσσα προγραμματισμού Rust. Σύνταξη γλώσσας προγραμματισμού

Είμαι νέος στη Rust, αλλά γρήγορα γίνεται η αγαπημένη μου γλώσσα προγραμματισμού. Ενώ η σύνταξη μικρών έργων στο Rust είναι συνήθως λιγότερο εργονομική και διαρκεί περισσότερο (τουλάχιστον με εμένα στο τιμόνι), όντως προκαλεί τον τρόπο με τον οποίο σκέφτομαι τον σχεδιασμό του προγράμματος. Οι μάχες μου με τον μεταγλωττιστή γίνονται λιγότερο συχνές αφού μάθω κάτι νέο.

Η κοινότητα Rust έχει επικεντρώσει πρόσφατα πολλές από τις προσπάθειές της στην ασύγχρονη I/O, που υλοποιείται με τη μορφή της βιβλιοθήκης Tokio. Και αυτό είναι υπέροχο.

Πολλά από τα μέλη της κοινότητας, αυτά που δεν έχουν εργαστεί με διακομιστές ιστού και σχετικά πράγματα, δεν είναι ξεκάθαρα για το τι θέλουμε να επιτύχουμε. Όταν αυτά τα πράγματα συζητήθηκαν πριν από 1,0 ημέρες, είχα και εγώ μια αόριστη ιδέα για αυτό, καθώς δεν είχα ξαναδουλέψει με αυτό.

  • Τι είναι - Async I/O?
  • Τι είναι οι κορουτίνες; κορουτίνες )?
  • Τι είναι τα ελαφριά νήματα ( ελαφριές κλωστές )?
  • Τι είναι τα συμβόλαια μελλοντικής εκπλήρωσης; ( συμβόλαια μελλοντικής εκπλήρωσης )?

  • Πώς ταιριάζουν μεταξύ τους;

Θα σας δείξω πώς να γράψετε ένα μικρό πρόγραμμα που κατεβάζει μια ροή ( ταίζω) σε μορφή JSON, αναλύει και εμφανίζει μια λίστα σημειώσεων στην κονσόλα σε μορφοποιημένη μορφή.

Για εμάς, όλα κατέληξαν σε έναν πολύ συνοπτικό κώδικα. Πως? Κοιτάξτε κάτω από το κόψιμο.

Η μη ασφαλής λέξη-κλειδί αποτελεί αναπόσπαστο μέρος του σχεδιασμού της γλώσσας Rust. Για όσους δεν είναι εξοικειωμένοι με αυτό, το unsafe είναι μια λέξη-κλειδί που, με απλά λόγια, είναι ένας τρόπος παράκαμψης του ελέγχου τύπου( έλεγχος τύπου) Σκουριά.

Η ύπαρξη της μη ασφαλούς λέξης-κλειδιού αποτελεί έκπληξη για πολλούς στην αρχή. Πράγματι, δεν είναι χαρακτηριστικό του Rust ότι τα προγράμματα δεν κολλάνε από σφάλματα μνήμης; Εάν αυτό ισχύει, τότε γιατί υπάρχει ένας εύκολος τρόπος να παρακάμψουμε το σύστημα τύπου; Αυτό μπορεί να φαίνεται σαν ελάττωμα σχεδιασμού γλώσσας.

Ωστόσο, κατά τη γνώμη μου, το μη ασφαλές δεν είναι μειονέκτημα. Στην πραγματικότητα, είναι ένα σημαντικό μέρος της γλώσσας. Το μη ασφαλές λειτουργεί ως ένα είδος βαλβίδας διαφυγής - αυτό σημαίνει ότι μπορούμε να χρησιμοποιήσουμε το σύστημα τύπου σε απλές περιπτώσεις, αλλά και πάλι επιτρέπουμε κάθε είδους έξυπνα κόλπα που θέλετε να χρησιμοποιήσετε στον κώδικά σας. Απαιτούμε μόνο να κρύψετε αυτές τις τεχνικές (μη ασφαλής κώδικας) πίσω από ασφαλείς εξωτερικές αφαιρέσεις.

Αυτή η σημείωση εισάγει τη λέξη-κλειδί μη ασφαλής και την ιδέα της περιορισμένης "ανασφάλειας". Στην πραγματικότητα, αυτό είναι προάγγελος μιας σημείωσης που ελπίζω να γράψω λίγο αργότερα. Συζητά το μοντέλο μνήμης του Rust, το οποίο καθορίζει τι μπορεί και τι δεν μπορεί να γίνει σε μη ασφαλή κώδικα.

Ως αρχάριος στο Rust, είχα μπερδευτεί σχετικά με τους διαφορετικούς τρόπους αναπαράστασης χορδών. Το βιβλίο για τη γλώσσα Rust έχει ένα κεφάλαιο που ονομάζεται Αναφορές και Δανεισμός, το οποίο χρησιμοποιεί τρεις διαφορετικούς τύπους μεταβλητών συμβολοσειρών σε παραδείγματα: String, &String και &str.

Ας ξεκινήσουμε με τη διαφορά μεταξύ str και String: Η συμβολοσειρά είναι μια επεκτάσιμη δομή δεδομένων που εκχωρείται σε σωρό, ενώ η str είναι μια αμετάβλητη συμβολοσειρά σταθερού μήκους. κάπουστο μυαλό.

Πολλοί προγραμματιστές γνωρίζουν ήδη πώς να προγραμματίζουν σε αντικειμενοστρεφείς γλώσσες. Η Rust δεν είναι μια κλασική αντικειμενοστραφή γλώσσα, αλλά βασικά εργαλεία OOP μπορούν να χρησιμοποιηθούν σε αυτήν.

Σε αυτό το άρθρο θα δούμε πώς να προγραμματίζουμε στο Rust σε στυλ OOP. Θα το κάνουμε αυτό χρησιμοποιώντας ένα παράδειγμα: θα δημιουργήσουμε μια ιεραρχία κλάσεων σε μια εκπαιδευτική εργασία.

Το καθήκον μας είναι να δουλέψουμε με γεωμετρικά σχήματα. Θα τα εμφανίσουμε στην οθόνη σε μορφή κειμένου και θα υπολογίσουμε την περιοχή τους. Το σύνολο των σχημάτων μας είναι ορθογώνιο, τετράγωνο, έλλειψη, κύκλος.

Η σκουριά είναι μια κομψή γλώσσα που είναι κάπως διαφορετική από πολλές άλλες δημοφιλείς γλώσσες. Για παράδειγμα, αντί να χρησιμοποιεί κλάσεις και κληρονομικότητα, η Rust προσφέρει το δικό της σύστημα τύπων που βασίζεται σε χαρακτηριστικά. Ωστόσο, πιστεύω ότι πολλοί προγραμματιστές που ξεκινούν τη γνωριμία τους με το Rust (όπως εγώ) δεν είναι εξοικειωμένοι με τα γενικά αποδεκτά σχέδια σχεδίασης.

Σε αυτό το άρθρο, θέλω να συζητήσω το σχέδιο σχεδίασης νέου τύπου(νέος τύπος), καθώς και τα χαρακτηριστικά From και Into, τα οποία βοηθούν στη μετατροπή τύπου.

Τον τελευταίο καιρό σκέφτομαι πολύ τα μοτίβα σχεδίασης και τις τεχνικές που χρησιμοποιούμε στον προγραμματισμό. Είναι πραγματικά υπέροχο να αρχίσετε να εξερευνάτε ένα έργο και να βλέπετε γνωστά μοτίβα και στυλ που έχετε δει πολλές φορές στο παρελθόν. Αυτό διευκολύνει την κατανόηση του έργου και καθιστά δυνατή την επιτάχυνση της εργασίας.

Μερικές φορές εργάζεστε σε ένα νέο έργο και συνειδητοποιείτε ότι πρέπει να κάνετε κάτι με τον ίδιο τρόπο που το κάνατε στο τελευταίο έργο. Μπορεί να μην είναι ένα κομμάτι λειτουργικότητας ή βιβλιοθήκης, μπορεί να είναι κάτι που δεν μπορεί να τυλιχθεί σε ένα προσεγμένο μακροεντολή ή μικρό δοχείο. Μπορεί απλώς να είναι ένα σχέδιο σχεδίασης ή μια δομική ιδέα που λύνει καλά το πρόβλημα.

Ένα ενδιαφέρον μοτίβο που εφαρμόζεται συχνά σε τέτοια προβλήματα είναι η «Μηχανή πεπερασμένης κατάστασης». Προτείνω να αφιερώσετε λίγο χρόνο για να καταλάβετε τι ακριβώς σημαίνει αυτή η φράση και γιατί είναι τόσο ενδιαφέρουσα.

Ακολουθεί μια γραφική περιγραφή της μετακίνησης, της αντιγραφής και του δανεισμού στη γλώσσα προγραμματισμού Rust. Βασικά, αυτές οι έννοιες είναι συγκεκριμένες για το Rust και συχνά αποτελούν εμπόδιο για αρχάριους.

Για να αποφύγω τη σύγχυση, προσπάθησα να περιορίσω το κείμενο στο ελάχιστο. Αυτή η σημείωση δεν αντικαθιστά διάφορα σεμινάρια και είναι φτιαγμένη μόνο για όσους πιστεύουν ότι οι οπτικές πληροφορίες γίνονται πιο εύκολα αντιληπτές. Εάν μόλις αρχίζετε να μαθαίνετε το Rust και βρίσκετε αυτά τα γραφήματα χρήσιμα, θα συνιστούσα να επισημάνετε τον κώδικά σας με παρόμοια γραφήματα για να ενισχύσετε τις έννοιες.

Η εφαρμογή αριθμητικής φυσικών αριθμών με χρήση αριθμών Peano είναι μια δημοφιλής εργασία στη διδασκαλία του προγραμματισμού. Αναρωτιόμουν αν ήταν δυνατή η εφαρμογή τους στο Rust.

Έτσι, το καθήκον μου είναι να σημειώνω και να προσθέτω φυσικούς αριθμούς με έλεγχο τύπου.

Σύμφωνα με τη Wikipedia, «τα αξιώματα του Peano είναι ένα από τα συστήματα αξιωμάτων για φυσικούς αριθμούς, που εισήχθη τον 19ο αιώνα από τον Ιταλό μαθηματικό Giuseppe Peano».

Μας ενδιαφέρουν δύο από αυτά - με τα οποία μπορείτε να εισαγάγετε και να χρησιμοποιήσετε φυσικούς αριθμούς:

  • Το 1 είναι φυσικός αριθμός
  • Ο αριθμός που ακολουθεί τον φυσικό αριθμό είναι επίσης φυσικός αριθμός.

Ας το γράψουμε αυτολεξεί σε σκουριά χρησιμοποιώντας:

1 2 3 4 enum Nat(Μηδέν, Succ(Nat))

Το Nat είναι είτε μηδέν είτε ο επόμενος φυσικός αριθμός.

Σχόλιο: Το project futures-rs έχει αναδιοργανωθεί και πολλά πράγματα έχουν μετονομαστεί. Όπου είναι δυνατόν, οι σύνδεσμοι έχουν ενημερωθεί.

Ξεκινώντας με τα συμβόλαια μελλοντικής εκπλήρωσης

Αυτό το έγγραφο θα σας βοηθήσει να εξερευνήσετε το κοντέινερ της γλώσσας προγραμματισμού μελλοντικής εκπλήρωσης για το Rust, το οποίο παρέχει μηδενικού κόστους υλοποιήσεις συμβολαίων μελλοντικής εκπλήρωσης και νημάτων. Τα Futures είναι διαθέσιμα σε πολλές άλλες γλώσσες προγραμματισμού, όπως η C++, η Java και η Scala, και το μελλοντικό κοντέινερ εμπνέεται από τις βιβλιοθήκες αυτών των γλωσσών. Ωστόσο, είναι εργονομικό και συμμορφώνεται επίσης με τη φιλοσοφία της αφαίρεσης μηδενικού κόστους που είναι εγγενής στο Rust, δηλαδή: δεν απαιτούνται εκχωρήσεις μνήμης για τη δημιουργία και τη σύνθεση μελλοντικών συμβάσεων και απαιτείται μόνο μία κατανομή για το Task που τα διαχειρίζεται. Τα συμβόλαια μελλοντικής εκπλήρωσης προορίζονται να αποτελέσουν τη βάση για ασύγχρονες, συνθετικές εισόδους/εξόδους υψηλής απόδοσης στο Rust και οι πρώιμες μετρήσεις απόδοσης δείχνουν ότι ένας απλός διακομιστής HTTP που βασίζεται σε συμβόλαια μελλοντικής εκπλήρωσης είναι πράγματι γρήγορος.

Αυτή η τεκμηρίωση χωρίζεται σε διάφορες ενότητες:

  • "Γειά σου Κόσμε!";
  • μελλοντικός τύπος?
  • τύπος Stream ;
  • συγκεκριμένα συμβόλαια μελλοντικής εκπλήρωσης και ροή (Stream)·
  • επιστροφές συμβολαίων μελλοντικής εκπλήρωσης?
  • Καθήκον και μέλλον.
  • τοπικά δεδομένα εργασιών.

Σχόλιο: Το project futures-rs έχει αναδιοργανωθεί και πολλά πράγματα έχουν μετονομαστεί. Όπου είναι δυνατόν, οι σύνδεσμοι έχουν ενημερωθεί.

Ένα από τα σημαντικότερα κενά στο οικοσύστημα Rust ήταν γρήγορο και αποτελεσματικό ασύγχρονη I/O. Έχουμε μια γερή βάση από τη βιβλιοθήκη mio, αλλά είναι πολύ χαμηλού επιπέδου: πρέπει να δημιουργήσουμε χειροκίνητα μηχανήματα κατάστασης και να κάνουμε ταχυδακτυλουργικές επιστροφές κλήσεων.

Θα θέλαμε κάτι πιο high-end, με καλύτερη εργονομία, αλλά να έχει καλό συνθεσιμότητα, υποστηρίζοντας ένα οικοσύστημα ασύγχρονων αφαιρέσεων που συνεργάζονται. Ακούγεται πολύ οικείο: τον ίδιο στόχο επιδίωκε και η υλοποίηση συμβόλαια μελλοντικής εκπλήρωσης(ή υποσχέσεις) σε πολλές γλώσσες που υποστηρίζουν τη συντακτική ζάχαρη στη μορφή ασυγχρονισμός/αναμονήστην κορυφή.

Οι πρωτόγονοι τύποι ακεραίων που υποστηρίζονται από επεξεργαστές είναι μια περιορισμένη προσέγγιση του άπειρου συνόλου ακεραίων που έχουμε συνηθίσει να χειριζόμαστε στην πραγματική ζωή. Αυτή η περιορισμένη αναπαράσταση δεν ταιριάζει πάντα με τους "πραγματικούς" αριθμούς, για παράδειγμα 255_u8 + 1 == 0 . Συχνά ο προγραμματιστής ξεχνά αυτή τη διαφορά, η οποία μπορεί εύκολα να οδηγήσει σε σφάλματα.

Η Rust είναι μια γλώσσα προγραμματισμού που στοχεύει να είναι ανθεκτική σε σφάλματα, εστιάζοντας στην πρόληψη των πιο ύπουλων από αυτά - σφαλμάτων μνήμης - αλλά και προσπαθώντας να βοηθήσει τον προγραμματιστή να αποφύγει άλλα προβλήματα: αγνοούνται σφάλματα και, όπως θα δούμε, υπερχείλιση ακεραίων.

Λίγα λόγια για το Iron

Το Iron είναι ένα πλαίσιο ιστού υψηλού επιπέδου γραμμένο στη γλώσσα προγραμματισμού Rust και χτισμένο πάνω από μια άλλη γνωστή βιβλιοθήκη, την hyper. Το σίδερο έχει σχεδιαστεί για να εκμεταλλεύεται όλα τα οφέλη που μας παρέχει η Rust. Το Iron προσπαθεί να αποφύγει το μπλοκάρισμα των λειτουργιών στον πυρήνα του.

Φιλοσοφία

Ο σίδηρος βασίζεται στην αρχή του να είναι όσο το δυνατόν πιο εκτατό. Εισάγει έννοιες για να επεκτείνει τη δική του λειτουργικότητα:

  • "ενδιάμεσα" χαρακτηριστικά - που χρησιμοποιούνται για την υλοποίηση λειτουργιών από άκρο σε άκρο στην επεξεργασία αιτημάτων.
  • τροποποιητές - χρησιμοποιούνται για την τροποποίηση αιτημάτων και απαντήσεων με τον πιο εργονομικό τρόπο.

Θα εξοικειωθείτε με το βασικό μέρος των τροποποιητών και των ενδιάμεσων τύπων κατά τη διάρκεια του άρθρου.

Δημιουργία Έργου

Αρχικά, ας δημιουργήσουμε ένα έργο χρησιμοποιώντας Cargo χρησιμοποιώντας την εντολή:

Μετά τη μεταγλώττιση, παίρνουμε το αντίστοιχο εκτελέσιμο αρχείο:

1 2 3 $ rustc hello.rs $ du -h γεια 632K γεια

632 kilobyte για μια απλή εκτύπωση;! Η Rust τοποθετείται ως γλώσσα συστήματος που έχει τη δυνατότητα να αντικαταστήσει τη C/C++, σωστά; Γιατί λοιπόν να μην δοκιμάσετε ένα παρόμοιο πρόγραμμα στον πλησιέστερο ανταγωνιστή σας;

Υπάρχει μια ευρέως διαδεδομένη πεποίθηση στο περιβάλλον μας ότι ένα από τα πλεονεκτήματα ενός συλλέκτη σκουπιδιών είναι η ευκολία ανάπτυξης δομών δεδομένων υψηλής απόδοσης χωρίς κλείδωμα. Η χειροκίνητη διαχείριση μνήμης δεν είναι εύκολο να γίνει σε αυτά, αλλά η GC επιλύει εύκολα αυτό το πρόβλημα.

Αυτή η ανάρτηση θα δείξει ότι, χρησιμοποιώντας το Rust, είναι δυνατή η δημιουργία ενός API διαχείρισης μνήμης για ταυτόχρονες δομές δεδομένων που:

  • Θα καταστήσει δυνατή την εφαρμογή μιας δομής δεδομένων χωρίς κλείδωμα, όπως κάνει η GC.
  • Δημιουργεί στατική προστασία από κακή χρήση του συστήματος διαχείρισης μνήμης.
  • Θα έχει συγκρίσιμα γενικά έξοδα με τα GC (και πιο προβλέψιμα).

Στις δοκιμές που θα δείξω παρακάτω, το Rust ξεπερνά εύκολα τις υλοποιήσεις Java των ουρών χωρίς κλείδωμα και η ίδια η υλοποίηση Rust είναι εύκολο να γραφτεί.

Έχω εφαρμόσει ένα σχήμα ανάκτησης μνήμης με βάση την εποχή στη νέα βιβλιοθήκη Crossbeam, η οποία είναι τώρα έτοιμη για χρήση με τις δομές δεδομένων σας. Σε αυτήν την ανάρτηση θα μιλήσω για δομές δεδομένων χωρίς κλειδαριά, τον αλγόριθμο εποχής και το εσωτερικό Rust API.

Τα σφάλματα πρόσβασης στη μνήμη και οι διαρροές μνήμης είναι οι δύο κατηγορίες σφαλμάτων που τυγχάνουν της μεγαλύτερης προσοχής, οπότε καταβάλλεται μεγάλη προσπάθεια για την πρόληψη ή τουλάχιστον τη μείωση της εμφάνισής τους. Αν και το όνομά τους υποδηλώνει ομοιότητα, είναι κατά κάποιο τρόπο διαμετρικά αντίθετα και η επίλυση ενός από τα προβλήματα δεν μας απαλλάσσει από το δεύτερο. Η ευρεία χρήση των διαχειριζόμενων γλωσσών υποστηρίζει αυτήν την ιδέα: αποτρέπουν ορισμένα σφάλματα πρόσβασης στη μνήμη αναλαμβάνοντας το έργο της απελευθέρωσης της μνήμης.

Με απλά λόγια: μια παραβίαση πρόσβασης στη μνήμη είναι κάποιο είδος ενέργειας με λανθασμένα δεδομένα και μια διαρροή μνήμης είναι απουσίαορισμένες ενέργειες με σωστά δεδομένα. Σε μορφή πίνακα:

Έχω μερικές σκέψεις για την εκμάθηση γλωσσών προγραμματισμού.

Πρώτα απ 'όλα, το κάνουμε με λάθος τρόπο. Είμαι σίγουρος ότι έχεις νιώσει το ίδιο. Προσπαθείτε να μάθετε μια νέα γλώσσα και δεν καταλαβαίνετε πώς λειτουργούν όλα. Γιατί χρησιμοποιείται μια σύνταξη σε ένα μέρος και μια άλλη σε άλλο; Όλες αυτές οι παραξενιές είναι ενοχλητικές και στο τέλος επιστρέφουμε στη συνηθισμένη μας γλώσσα.

Πιστεύω ότι η αντίληψή μας για τις γλώσσες μας παίζει ένα σκληρό αστείο. Σκεφτείτε την τελευταία φορά που συζητήσατε μια νέα γλώσσα. Κάποιος το ανέφερε και κάποιος άλλος ρώτησε για την ταχύτητα, τη σύνταξη ή το διαθέσιμο πλαίσιο ιστού.

Αυτό μοιάζει πολύ με τη συζήτηση για αυτοκίνητα. Έχετε ακούσει για το νέο UAZ Rybak; Πόσο γρήγορος είναι; Μπορώ να το οδηγήσω στη λίμνη;

Όταν μιλάμε για γλώσσες με παρόμοιο τρόπο, εννοούμε ότι είναι εναλλάξιμες. Σαν αυτοκίνητα. Εάν ξέρω πώς να οδηγώ ένα Lada Saransk, τότε μπορώ να οδηγήσω ένα UAZ Rybak χωρίς κανένα πρόβλημα. Η μόνη διαφορά είναι η ταχύτητα και το ταμπλό, σωστά;

Φανταστείτε όμως πώς θα έμοιαζε ένα αυτοκίνητο PHP. Τώρα φανταστείτε πόσο διαφορετικό θα ήταν ένα αυτοκίνητο Lisp. Η αλλαγή από το ένα στο άλλο απαιτεί πολύ περισσότερα από το να μάθετε ποιο κουμπί ελέγχει τη θέρμανση.

Σημείωση: Αυτό το άρθρο υποθέτει ότι ο αναγνώστης είναι εξοικειωμένος με το Rust FFI (μετάφραση), το endianness και το ioctl.

Όταν δημιουργούμε δεσμεύσεις για τον κώδικα C, αναπόφευκτα θα συναντήσουμε μια δομή που περιέχει μια ένωση. Το Rust δεν έχει ενσωματωμένη υποστήριξη για συνδέσεις, επομένως θα πρέπει να σχεδιάσουμε τη στρατηγική μόνοι μας. Στο C, μια ένωση είναι ένας τύπος που αποθηκεύει διαφορετικούς τύπους δεδομένων στην ίδια περιοχή μνήμης. Υπάρχουν πολλοί λόγοι για να ευνοηθεί η συνένωση, όπως: μετατροπή μεταξύ δυαδικών αναπαραστάσεων ακεραίων και αριθμών κινητής υποδιαστολής, εφαρμογή ψευδοπολυμορφισμού και άμεση πρόσβαση σε bits. Θα επικεντρωθώ στον ψευδοπολυμορφισμό.


Μας άρεσε πολύ το άρθρο "Criticism of the Rust language and Why C/C++ will never die." Προτείναμε στον συγγραφέα να μεταφράσουμε το άρθρο στα αγγλικά και να το δημοσιεύσουμε επίσης στο ιστολόγιό μας. Συμφώνησε και είμαστε στην ευχάριστη θέση να παρουσιάσουμε αυτό το άρθρο στα ρωσικά και τα αγγλικά. Το αρχικό άρθρο βρίσκεται.

Το αρχικό άρθρο είναι αναρτημένο (κείμενο στα ρωσικά). Το άρθρο δημοσιεύτηκε στο blog μας με τη σύμφωνη γνώμη του συγγραφέα.

Σημείωση: Στη συνέχεια, κάνω την υπόθεση ότι το Rust είναι μια προσπάθεια να φτιάξουμε μια γρήγορη και ασφαλή γλώσσα. Εξάλλου, τα παιδιά της Mozilla το έφτιαξαν ως εργαλείο ανάπτυξης μηχανών προγράμματος περιήγησης. Αν αυτή είναι απλώς μια άλλη ασφαλής γλώσσα, τότε έχουμε κάτι περίεργο. Υπάρχουν ήδη μια δεκάρα δώδεκα διαφορετικές ασφαλείς γλώσσες, ο καθένας θα βρει κάτι της αρεσκείας του. Και αν ο στόχος δεν είναι η αντικατάσταση της C++, τότε (1) γιατί δημιουργείται ένα μη ασφαλές υποσύνολο στη γλώσσα; (2) γιατί ήταν απαραίτητο να αφαιρέσουμε ελαφριές ροές από τη γλώσσα; Δεν είναι βολικό; Με άλλα λόγια, σε αυτή την περίπτωση, αυτό που συμβαίνει δεν έχει κανένα απολύτως νόημα.

Εάν τυχαίνει να διαβάζετε το φόρουμ του linux.org.ru, θα σημειώσω ότι αυτή δεν είναι η λίστα με τους 10 καθαρά τεχνικούς λόγους για να μην σας αρέσει το Rust που συζητήθηκε σε αυτό το νήμα. Όπως φαίνεται από μια συζήτηση στο Skype με αγαπητέ σύντροφε @sum3rman, υπάρχουν περισσότερες από μία απόψεις σχετικά με το πόσο «τεχνικοί» πρέπει να θεωρηθούν αυτοί οι λόγοι. Γενικά, έφτιαξα μια άθλια λίστα, αλλά πιθανότατα θα διακινδυνεύσω να αναφέρω μερικά από τα πιο ενδιαφέροντα σημεία από αυτήν. Στην πραγματικότητα, υπάρχουν πολλοί απλοί, μη τεχνικοί λόγοι εδώ.

Το γεγονός ότι η C/C++ δεν θα πάει πουθενά στο άμεσο μέλλον είναι ξεκάθαρο σε κάθε νηφάλιο άτομο. Κανείς δεν θα ξαναγράψει σχεδόν όλες τις εφαρμογές επιτραπέζιου υπολογιστή, πυρήνες λειτουργικών συστημάτων, μεταγλωττιστές, μηχανές παιχνιδιών και προγράμματος περιήγησης, εικονικές μηχανές, βάσεις δεδομένων, αρχειοθέτες, κωδικοποιητές ήχου και βίντεο, τόνους άλλων βιβλιοθηκών που βασίζονται στη C και ούτω καθεξής. Αυτός είναι πολύ, πολύ γρήγορος, διορθωμένος κώδικας, δοκιμασμένος στο χρόνο. Το να το ξαναγράψεις είναι πολύ, πολύ ακριβό, ριψοκίνδυνο και για να είμαι ειλικρινής, έχει νόημα μόνο στην παραμορφωμένη συνείδηση ​​μόνο των πιο επίμονων οπαδών του Rust. Η ζήτηση για προγραμματιστές C/C++ ήταν και θα είναι μεγάλη για πολύ καιρό.

Εντάξει, τι γίνεται με τη χρήση του Rust κατά τη σύνταξη νέου κώδικα;

Ας θυμηθούμε ότι αυτή δεν είναι η πρώτη προσπάθεια να κάνουμε ένα «πιο σωστό» C/C++. Ας πάρουμε για παράδειγμα τη γλώσσα Δ. Εμφανίστηκε το 2001, μια πολύ καλή γλώσσα. Δεν υπάρχουν κενές θέσεις, δεν υπάρχουν κανονικά εργαλεία ανάπτυξης, δεν υπάρχουν ιδιαίτερα εξαιρετικές ιστορίες επιτυχίας. Το έργο OpenMW γράφτηκε αρχικά σε D και στη συνέχεια ξαφνικά αποφάσισαν να το ξαναγράψουν εξ ολοκλήρου σε C++. Όπως παραδέχονται οι προγραμματιστές, έλαβαν πολλές επιστολές με το στυλ του "εξαιρετικού έργου, θα χαρούμε να συνεισφέρουμε σε αυτό, αλλά δεν ξέρουμε και δεν θέλουμε να μάθουμε αυτό το ανόητο D." Η Wikipedia αναφέρει ότι εκτός από το D, υπήρξαν πολλές άλλες προσπάθειες να σκοτωθεί η C++ σε έναν ή τον άλλο βαθμό, για παράδειγμα, Vala, Cyclone, Limbo, BitC. Πόσοι άνθρωποι έχουν ακούσει για τέτοιες γλώσσες;

Νομίζω ότι είναι καιρός να μάθουμε από την ιστορία. Κανένας λογικός άνθρωπος δεν θα σύρει μια νέα γλώσσα σε ένα έργο μέχρι να του δείξεις τουλάχιστον κανονικά εργαλεία ανάπτυξης, να του πεις μερικές ιστορίες επιτυχίας και να του δείξεις μια ντουζίνα προγραμματιστές σε αυτή τη γλώσσα που ζουν κοντά. Οι προγραμματιστές, ίσως, εκτός από τους νεότερους, δεν θα σπαταλήσουν ποτέ τον χρόνο και την υγεία τους για να μάθουν την επόμενη πιο σωστή γλώσσα μέχρι να τους δείξετε κανονικά εργαλεία ανάπτυξης (όχι χειροτεχνίες όπως το Racer), μερικές δεκάδες χιλιάδες έτοιμες βιβλιοθήκες ( όχι «πειραματικά», «ασταθή» και ούτω καθεξής), μην πείτε μερικές ιστορίες επιτυχίας και δείξτε μια ντουζίνα ανοιχτές κενές θέσεις στην πόλη τους. Πρόβλημα με κοτόπουλο και αυγό. Πολύ σπάνια, αυτό το πρόβλημα μπορεί να λυθεί με επιτυχία (υπό όρους, η Scala μπορεί να αναφερθεί ως παράδειγμα), κυρίως λόγω της επένδυσης χρόνου και χρημάτων από την πλευρά κάποιας μεγάλης εταιρείας (Google, Typesafe), για κάποιο λόγο που ενδιαφέρεται να διαδώσει το Γλώσσα.

Όπως έχω ήδη σημειώσει, μόνο οι μη τεχνικοί λόγοι είναι υπεραρκετοί. Ωστόσο, καθαρά από περιέργεια, ας προσπαθήσουμε να φανταστούμε για λίγο ότι δεν είναι εκεί. Τότε δεν υπάρχει λόγος να μην γράφεις στο Rust; Αποδεικνύεται ότι αυτό είναι επίσης τουλάχιστον ένα πολύ μεγάλο ερώτημα.

Το C/C++ επικρίνεται για διάφορα πράγματα. Παρεμπιπτόντως, πολύ συχνά γίνεται κριτική από όσους δεν έχουν δει καν κώδικα C++ στην παραγωγή ούτε από μακριά. Το πρόβλημα μπορεί να περιγραφεί εν συντομία και με σαφήνεια ως εξής: Η C++ είναι πολύ γρήγορη (και επίσης δεν απαιτεί μνήμη, φόρτιση μπαταρίας κ.λπ.), αλλά δεν είναι ασφαλές με την έννοια ότι σας επιτρέπει να υπερβείτε τα όρια των συστοιχιών, να έχετε εσφαλμένη πρόσβαση ελευθερωμένα κομμάτια μνήμης, και ούτω καθεξής Περαιτέρω. Κάποτε, αυτό το πρόβλημα οδήγησε στην εμφάνιση μιας μάζας ασφαλών γλωσσών, όπως η Java, η C#, η Python και άλλες. Αλλά αποδείχθηκε ότι αυτές οι γλώσσες, σε σύγκριση με τη C++, απαιτούν υπερβολικά πόρους και έχουν άλλα μειονεκτήματα, για παράδειγμα, την αναπόφευκτη στάση του κόσμου κατά τη συλλογή σκουπιδιών. Επομένως, οι άνθρωποι παλεύουν με το καθήκον να κάνουν μια γλώσσα τόσο γρήγορη όσο η C++, αλλά και ασφαλή. Μια τέτοια γλώσσα είναι η Rust.

Η σκουριά είναι πράγματι ασφαλής, αλλά δυστυχώς, απέχει πολύ από το να είναι γρήγορη. Κατά τη στιγμή της γραφής, το Rust είναι συγκρίσιμο σε ταχύτητα με τα Java, Go και Haskell:

Ελπίζω ειλικρινά ότι με τον καιρό θα γίνει με κάποιο τρόπο overclocked, αλλά μέχρι τότε, όσον αφορά την ταχύτητα και την ασφάλεια, δεν είναι πολύ πιο ενδιαφέρον από το Scala ή το Go. Το ερώτημα παραμένει ανοιχτό εάν είναι δυνατό να γίνει μια γλώσσα γρήγορη και ασφαλής καθόλου, ή εάν οι συνεχείς έλεγχοι για υπέρβαση των ορίων πίνακα, ασφαλείς δεσμεύσεις γύρω από δεσμεύσεις σε βιβλιοθήκες C και ούτω καθεξής κάνουν αυτόματα οποιαδήποτε γλώσσα 2 φορές πιο αργή από τη C/ C++.

Τι ακριβώς κάνει το Rust ασφαλές; Με απλά λόγια, είναι μια γλώσσα με ενσωματωμένο αναλυτή στατικού κώδικα. Ένας πραγματικά πολύ καλός στατικός αναλυτής που καταγράφει όλα τα τυπικά σφάλματα C++, όχι μόνο αυτά που σχετίζονται με τη διαχείριση της μνήμης, αλλά και το multithreading. Πέρασα έναν σύνδεσμο προς ένα μεταβλητό αντικείμενο σε ένα άλλο νήμα μέσω ενός καναλιού και, στη συνέχεια, προσπάθησα να χρησιμοποιήσω αυτόν τον σύνδεσμο - δεν έγινε μεταγλώττιση. Είναι πραγματικά ωραίο.

Συχνά διατυπώνεται το επιχείρημα ότι μόνο το 10% του κώδικα εκτελείται το 90% των περιπτώσεων (το οποίο, από όσο καταλαβαίνω, είναι καθαρά εμπειρικός κανόνας - δεν μπόρεσα να βρω γρήγορα καμία αυστηρή έρευνα για αυτό το θέμα). Επομένως, το μεγαλύτερο μέρος του προγράμματος μπορεί να γραφτεί σε ασφαλή Rust, με το 10% του ζεστού κώδικα γραμμένο στο μη ασφαλές υποσύνολο και η βραδύτητα της τρέχουσας εφαρμογής Rust δεν αποτελεί πραγματικά πρόβλημα. Εντάξει, αλλά μετά αποδεικνύεται ότι το Rust δεν χρειάζεται καθόλου, γιατί μπορώ να γράψω το 90% του κώδικα στο Go και το 10% στο C. Μόνο όσοι αναζητούν ασημένιες σφαίρες και θεωρητικοί που δεν έχουν καμία επαφή θα χρησιμοποιήσουν το Rust αποκλειστικά και μόνο για τον λόγο ότι το 100% του προγράμματος μπορεί να γραφτεί σε μία γλώσσα. Αν και στην πραγματικότητα πρόκειται για δύο διαλέκτους της ίδιας γλώσσας, κάτι που δεν διαφέρει τόσο από τον συνδυασμό Java + C ή Go + C.

Στην πραγματικότητα, ο κανόνας 10:90 εξακολουθεί να είναι ψέμα. Με αυτή τη λογική, θα μπορούσατε να ξαναγράψετε το 90% του WebKit, το 90% του VirtualBox ή το 90% του GCC σε Java και να έχετε το ίδιο αποτέλεσμα. Προφανώς αυτό δεν ισχύει. Ακόμα κι αν το θέμα δεν είναι ότι σε πολλά προγράμματα αυτή η στάση είναι πολύ διαφορετική, τότε προσέξτε τα χέρια σας. Ας υποθέσουμε ότι ολόκληρο το πρόγραμμα είναι γραμμένο σε μη ασφαλή C/C++ και ο χρόνος εκτέλεσής του, σχετικά μιλώντας, είναι ίσος με 0,9*1 (ένα μικρό μέρος του ζεστού κώδικα) + 0,1*1 (πολύς ψυχρός κώδικας) = 1. Τώρα ας συγκρίνετε το με ένα πρόγραμμα σε ασφαλή γλώσσα με ένθετα σε Si: 0,9*1 + 0,1*2 = 1,1, περίπου το 10% της διαφοράς. Αυτό είναι πολύ ή λίγο; Εξαρτάται από την κλίμακα σας. Στην περίπτωση της Google, ακόμη και λίγα τοις εκατό μπορούν να εξοικονομήσουν εκατομμύρια δολάρια (βλ. σημείο 5 στο έγγραφο, «Αξιοποίηση»). Ή φανταστείτε ότι με την επόμενη ενημέρωση το JVM αρχίζει ξαφνικά να απαιτεί 10% περισσότερους πόρους! Φοβάμαι ακόμη και να μαντέψω πόσα μηδενικά θα υπάρχουν στον αριθμό που προκύπτει μετά τη μετατροπή των τόκων σε αμερικανικά χρήματα! Το 10% είναι πολύ σε εργασίες όπου χρησιμοποιούνται C και C++.

Επαναλαμβάνουμε «η πρόωρη βελτιστοποίηση είναι η ρίζα όλου του κακού» σαν μάντρα. Αλλά αν το πάρουμε κυριολεκτικά, ας χρησιμοποιήσουμε την ταξινόμηση με φυσαλίδες αντί για τη γρήγορη ταξινόμηση παντού. Δεν γνωρίζουμε με βεβαιότητα ότι το πρόγραμμα θα επιβραδυνθεί στο συγκεκριμένο μέρος! Τι νόημα έχει να τυλίξετε τους συνηθισμένους μετρητές ορισμένων ενεργειών σε ηθοποιούς ή μνήμη συναλλαγών εάν μπορείτε να χρησιμοποιήσετε αμέσως το πιο αποτελεσματικό ατομικό; Και γενικά, σε ασήμαντες περιπτώσεις δεν έχει νόημα να αρχικοποιούμε αναγκαστικά όλες, όλες, όλες τις μεταβλητές, να κάνουμε ένα σωρό πρόσθετους ελέγχους και ούτω καθεξής. Ας καταλήξουμε με όχι 10% επιτάχυνση, αλλά 2-5%. Αυτό επίσης δεν είναι καθόλου κακό, αν χρειαζόταν μόνο μερικά επιπλέον λεπτά σκέψης. Και όπως έχουμε ήδη ανακαλύψει, σε προβλήματα που λύνονται σε C/C++, αυτό μπορεί να είναι μεγάλη διαφορά! Τότε, ποιος είπε ότι το να βρεις ένα hot spot, να ξαναγράψεις τον κώδικα (πιθανώς πολύ κώδικα) και να αποδείξεις ότι είναι πραγματικά πιο γρήγορο είναι πιο εύκολο από το να σκεφτείς την απόδοση εκ των προτέρων;

Αν αγνοήσουμε το ζήτημα της αντιστάθμισης ταχύτητας-ασφάλειας, έχω επίσης ερωτήσεις σχετικά με τον σχεδιασμό της ίδιας της γλώσσας. Ειδικότερα, όσον αφορά τους πέντε τύπους δεικτών. Από τη μία πλευρά, αυτό δεν είναι κακό όταν ο προγραμματιστής σκέφτεται πού βρίσκονται οι μεταβλητές, στη στοίβα ή στο σωρό, και αν πολλά νήματα μπορούν ή δεν μπορούν να λειτουργήσουν μαζί τους ταυτόχρονα. Αλλά από την άλλη πλευρά, φανταστείτε ότι γράφετε ένα πρόγραμμα και αποδεικνύεται ότι η μεταβλητή δεν πρέπει να ζει στη στοίβα, αλλά στο σωρό. Ξαναγράφετε τα πάντα για να χρησιμοποιήσετε το Box. Καταλαβαίνετε λοιπόν ότι αυτό που πραγματικά χρειάζεστε είναι το Rc ή το Arc. Ξαναγράφεις. Και μετά το ξαναγράφετε ξανά σε μια κανονική μεταβλητή στη στοίβα. Όλα αυτά - χωρίς ένα κανονικό IDE στο χέρι. Και τα κανονικά παιχνίδια δεν θα βοηθήσουν. Λοιπόν, ή απλώς στο στυλ του "Vec" >>>", γεια σου, Java! Αλλά το πιο λυπηρό είναι ότι ο μεταγλωττιστής γνωρίζει ήδη τη διάρκεια ζωής όλων των μεταβλητών, θα μπορούσε να εξάγει αυτόματα όλα αυτά τα Box, Arc και ούτω καθεξής. Αλλά για κάποιο λόγο αυτό το μέρος της εργασίας μεταφέρεται Πολύ πιο βολικό θα ήταν εύκολο να γραφτεί val (στην τρίτη χιλιετία!), και όπου είναι απαραίτητο, να υποδειχθεί ρητά το Box ή το Rc. Οι προγραμματιστές της Rust με αυτή την έννοια κατέστρεψαν την όλη ιδέα.

Εξαιτίας αυτού, ειδικότερα, το πεδίο εφαρμογής του Rust περιορίζεται σημαντικά. Κανείς με το σωστό μυαλό του δεν θα έγραφε το web και το serverside σε μια τέτοια γλώσσα. Ειδικά λαμβάνοντας υπόψη ότι δεν παρέχει σημαντικά πλεονεκτήματα σε σχέση με τις ίδιες γλώσσες στο πλαίσιο του JVM. Και το Go με κανονικά ελαφριά νήματα (όχι μελλοντικά) φαίνεται πολύ πιο ελκυστικό για αυτές τις εργασίες. Με το μέλλον, για να μην πυροβολήσεις τον εαυτό σου στο πόδι, πρέπει ακόμα να μάθεις πώς να δουλεύεις και λες «ασφαλή γλώσσα». Ναι, αυτές οι γλώσσες έχουν τα δικά τους χαρακτηριστικά, κάνουν την ίδια στάση στον κόσμο, αλλά αυτό το πρόβλημα μπορεί να λυθεί τόσο με την περικοπή σε μικροϋπηρεσίες όσο και με άλλες τεχνικές. Και ναι, κανείς δεν θα μεταφράσει το Rust σε JavaScript, δεν θα γράψει σενάρια σε αυτό για διάταξη στο AWS ή δεν θα το χρησιμοποιήσει ως γλώσσα ερωτημάτων για το MongoDB. Είναι επίσης απίθανο να γράψουν για Android, αλλά για διαφορετικό λόγο - υπάρχουν πολύ περισσότερες από μία αρχιτεκτονικές και είναι πολύ πιο εύκολο με το JVM. Αν ξαφνικά σκεφτήκατε ότι το Rust ήταν «κατάλληλο για όλες τις εργασίες», πρέπει να σας απογοητεύσω.

Λοιπόν, στο σωρό:

  • Οι μακροεντολές είναι ένα εφεδρικό αντίγραφο για την υπερβολική πολυλεκτικότητα που προκαλείται από την έλλειψη κανονικών εξαιρέσεων. Έχω ήδη γράψει για τα προβλήματα του μεταπρογραμματισμού, συγκεκριμένα, είναι απίθανο να δούμε ένα κανονικό IDE για το Rust εξαιτίας του. Και δεν είμαι σίγουρος, αλλά φαίνεται ότι οι μακροεντολές στο Rust δεν έχουν καν χώρους ονομάτων.
  • Οι άνθρωποι είναι ηλίθιοι και το φορτίο ενθαρρύνει πραγματικά να τραβούν πακέτα απευθείας από τα αποθετήρια git, παρακάμπτοντας το Crates.io. Ως αποτέλεσμα, υπάρχει μεγάλη πιθανότητα να δημιουργηθεί το ίδιο χάος με τα πακέτα όπως στον κόσμο του Erlang με το Rabar του. Παρεμπιπτόντως, στον κόσμο του Go, φαίνεται να είναι η ίδια κατάσταση.
  • Όπως πολλές νέες γλώσσες, η Rust ακολουθεί τον δρόμο της απλοποίησης. Γενικά, καταλαβαίνω γιατί δεν υπάρχει κανονική κληρονομιά και εξαιρέσεις σε αυτό, αλλά το ίδιο το γεγονός ότι κάποιος αποφασίζει τέτοια πράγματα για μένα αφήνει μια δυσάρεστη επίγευση. Η C++ δεν περιορίζει τον προγραμματιστή ως προς το τι πρέπει να χρησιμοποιήσει και τι όχι.
  • Εάν επρόκειτο να ακολουθήσουμε το μονοπάτι της απλοποίησης, τότε θα έπρεπε να πετάξουμε όλες αυτές τις γλωσσικές επεκτάσεις. Διαφορετικά, αποδεικνύεται, όπως και στον κόσμο του Haskell, ο κάθε προγραμματιστής γράφει στη δική του διάλεκτο.
  • Οι έξυπνοι δείκτες, αν μη τι άλλο, δεν είναι καθόλου δωρεάν και δεν οδηγούν σε προβλέψιμους χρόνους συλλογής σκουπιδιών. Κάποιο νήμα ξαφνικά έχει την τιμή να ελευθερώσει μια πολύ βαθιά δομή δεδομένων. Ενώ περπατά μέσα στο λαβύρινθο των νεκρών συνδέσμων, τα νήματα που εξαρτώνται από αυτόν υπομονετικά γίνονται ανόητα. Το ίδιο πρόβλημα υπάρχει και στο Erlang με τις μικρές του ομάδες, το έχω παρατηρήσει ο ίδιος περισσότερες από μία φορές. Οι έξυπνοι δείκτες έχουν επίσης τα δικά τους προβλήματα, τον ίδιο κατακερματισμό μνήμης και διαρροές. Ξέχασα το vikpointer στην κυκλική δομή, αυτό είναι όλο. Και αυτό σε μια γλώσσα που ισχυρίζεται ότι είναι ασφαλής. Εάν θέλετε προβλέψιμο χρόνο GC, είτε μελετήστε τη συμπεριφορά της εφαρμογής σας υπό φόρτωση και αναλάβετε δράση (θυμηθείτε τις ίδιες ομάδες αντικειμένων) εάν η ώρα GC δεν σας ταιριάζει, είτε διαχειριστείτε τη μνήμη χειροκίνητα.
  • Έχει δει κανείς μια αυστηρή περιγραφή της σημασιολογίας του Rust; Έχει τουλάχιστον μοντέλο μνήμης; Επίσης για μένα μια «ασφαλή» γλώσσα που «αποδεικνύει την ορθότητα» των προγραμμάτων, η οποία μπορεί πραγματικά να ερμηνεύσει τον πηγαίο κώδικα με δέκα διαφορετικούς τρόπους, χα!
  • Δεν μπορώ να μην σας το υπενθυμίσω για άλλη μια φορά Το πρόβλημα είναι σχεδόν πάντα οι άνθρωποι, όχι η τεχνολογία.. Εάν καταλήξετε με κακό κώδικα C++ ή η Java επιβραδύνει ξαφνικά, δεν είναι επειδή η τεχνολογία είναι κακή, αλλά επειδή δεν έχετε μάθει πώς να τη χρησιμοποιείτε σωστά. Θα είστε επίσης δυσαρεστημένοι με το Rust, αλλά για διαφορετικούς λόγους. Δεν θα ήταν πιο εύκολο να μάθετε να χρησιμοποιείτε και να αγαπάτε πιο δημοφιλή εργαλεία;

Γενικά, τα επόμενα 5 χρόνια θα προτιμούσα να επενδύσω τον χρόνο μου στην εκμάθηση C/C++ παρά στο Rust. C++ - αυτό είναι ένα βιομηχανικό πρότυπο. Μια μεγάλη ποικιλία προβλημάτων έχουν λυθεί με επιτυχία σε αυτή τη γλώσσα για περισσότερα από 30 χρόνια. Και το Rust και άλλα παρόμοια είναι ακατανόητα παιχνίδια με θολό μέλλον. Υπήρχαν συζητήσεις σχετικά με τον επικείμενο θάνατο της C++ τουλάχιστον από τη δεκαετία του 2000, αλλά η συγγραφή σε C/C++ άρχισε όχι λιγότερο κατά τη διάρκεια αυτής της περιόδου. Το αντίθετο μάλιστα. Και βλέπουμε ότι η γλώσσα αναπτύσσεται (C++11, C++14), εμφανίζονται νέα εργαλεία για αυτήν (ας θυμηθούμε τα CLion και Clang) και απλώς υπάρχουν πολλές αντίστοιχες κενές θέσεις.

Ένας προγραμματιστής C++ μπορεί πάντα να βρει εύκολα δουλειά με περισσότερο από αξιοπρεπή μισθό και, αν χρειαστεί, να επανεκπαιδευτεί γρήγορα στο Rust. Το αντίθετο είναι πολύ, πολύ αμφίβολο. Παρεμπιπτόντως, η γλώσσα, αν μη τι άλλο, απέχει πολύ από το μόνο και όχι τον καθοριστικό παράγοντα κατά την επιλογή ενός νέου τόπου εργασίας. Επιπλέον, ένας έμπειρος προγραμματιστής C/C++ μπορεί εύκολα να σκάψει στον πηγαίο κώδικα PostgreSQL ή στον πυρήνα του Linux, να χρησιμοποιήσει ισχυρά σύγχρονα εργαλεία ανάπτυξης και επίσης να έχει πολλά βιβλία και άρθρα στη διάθεσή του (ας πούμε στο OpenGL).

Φροντίστε τον χρόνο και την υγεία σας, δεν έχετε τόσο πολύ όσο νομίζετε!



Σήμερα, η σύνταξη Rust υποστηρίζεται σε vim και emacs χρησιμοποιώντας αρχεία σύνταξης που παρέχονται με τον μεταγλωττιστή.
Υπάρχουν επίσης πακέτα σύνταξης για το δημοφιλές ιδιόκτητο πρόγραμμα επεξεργασίας Sublime Text 2 και το δωρεάν πρόγραμμα επεξεργασίας Kate. Δεν υπάρχει ακόμη υποστήριξη για το Rust στο IDE. Δεν φαίνεται να υπάρχει ούτε υποστήριξη εντοπισμού σφαλμάτων.

Τα ακόλουθα βοηθητικά προγράμματα παρέχονται με τον μεταγλωττιστή rustc:
> rustdoc- ένα βοηθητικό πρόγραμμα για την αυτόματη δημιουργία τεκμηρίωσης από τον πηγαίο κώδικα όπως το Doxygen.
> rustpkg- ένας διαχειριστής πακέτων που σας επιτρέπει να εγκαταστήσετε εύκολα πρόσθετα πακέτα και βιβλιοθήκες.
> rusti- το λεγόμενο βοηθητικό πρόγραμμα REPL (read-eval-print-loop). Αυτός είναι ουσιαστικά ένας δοκιμαστικός διερμηνέας που παίρνει μια έκφραση Rust από τη γραμμή εντολών, τη μεταγλωττίζει σε μια εσωτερική αναπαράσταση LLVM, την εκτελεί και εκτυπώνει το αποτέλεσμα.
> σκουριά- ένα καθολικό βοηθητικό πρόγραμμα που εκκινεί άλλα βοηθητικά προγράμματα ή έναν μεταγλωττιστή ανάλογα με τις παραμέτρους. Δεν μου λειτούργησε ποτέ.

Όλη η διαθέσιμη τεκμηρίωση για τη γλώσσα συλλέγεται στον επίσημο ιστότοπο www.rust-lang.org. Υπάρχει ένα λεπτομερές εγχειρίδιο (http://static.rust-lang.org/doc/tutorial.html) - ολοκληρωμένη επίσημη τεκμηρίωση για όλες τις αποχρώσεις της σύνταξης, του μοντέλου μνήμης, του συστήματος χρόνου εκτέλεσης κ.λπ., καθώς και τεκμηρίωση σχετικά με η ενσωματωμένη βιβλιοθήκη πυρήνα και η τυπική βιβλιοθήκη std. Όλα τα έγγραφα είναι στα Αγγλικά. Δεν υπάρχει τρέχον υλικό στα ρωσικά και μερικά υπάρχοντα άρθρα κριτικής είναι ήδη πολύ ξεπερασμένα.

Ιδεολογία και σύνταξη


Η Rust είναι μια γλώσσα τύπου C που χρησιμοποιεί σγουρά άγκιστρα για να διαχωρίσει μπλοκ κώδικα. Η γλώσσα είναι «πολυπαράδειγμα», δηλ. σας επιτρέπει να γράψετε κώδικα με επιτακτικό-διαδικαστικό, αντικειμενοστραφή, ταυτόχρονο ή λειτουργικό τρόπο. Το Rust μεταγλωττίζεται σε εγγενή δυαδικό κώδικα σε οποιαδήποτε υποστηριζόμενη πλατφόρμα (χρησιμοποιεί το LLVM ως backend). Θεωρητικά, ο κώδικας Rust θα πρέπει να είναι τόσο γρήγορος όσο ο κώδικας C/C++. Το Rust τοποθετείται ως γλώσσα συστήματος, αλλά δεν έχει ενσωματωμένη υποστήριξη για μπλοκ κώδικα συναρμολόγησης όπως οι «αληθινές» γλώσσες συστημάτων C, C++ ή D.

Το μοντέλο μνήμης του Rust εγγενώς δεν επιτρέπει μηδενικούς ή κρέμονται δείκτες και υπερχειλίσεις buffer. Υπάρχει ένας προαιρετικός συλλέκτης απορριμμάτων που λειτουργεί μόνο μέσα σε ένα νήμα κώδικα. Η γλώσσα έχει ενσωματωμένη υποστήριξη για ελαφριά πολυεργασία και επικοινωνία μεταξύ νημάτων με χρήση μηνυμάτων. Η κοινή μνήμη δεν υπάρχει καθόλου στο Rust. Όλες οι μεταβλητές χωρίζονται σε μεταβλητές στοίβας, σε μεταβλητές σωρού για ένα δεδομένο νήμα και στις λεγόμενες μεταβλητές σωρού "ανταλλαγής", οι οποίες μπορούν να διαβαστούν από όλα τα νήματα, αλλά δεν μπορούν να αλλάξουν από αυτά. Αυτό εξαλείφει αυτόματα το αδιέξοδο, το οποίο θεωρείται η μάστιγα του προγραμματισμού πολλαπλών νημάτων. Το ABI της γλώσσας είναι συμβατό με το C, επομένως τα προγράμματα Rust μπορούν να συνδεθούν με βιβλιοθήκες γραμμένες σε C χωρίς πρόσθετα περιτυλίγματα. Για τις ανάγκες του προγραμματισμού συστήματος χαμηλού επιπέδου και για τη διασφάλιση της συμβατότητας με το C, η γλώσσα διαθέτει μια ειδική «μη ασφαλή» λειτουργία χωρίς έλεγχο της ορθότητας των δεικτών. Στην ιδεολογία του, το Rust είναι πιο κοντά στη γλώσσα Go. Όπως και στο Go, η κύρια έμφαση δίνεται στην απλότητα του προγραμματισμού πολλαπλών νημάτων και στην ταχύτητα ανάπτυξης εφαρμογών μεγάλης κλίμακας, ενώ η σύνταξη είναι επίσης ασυνήθιστη και κάπως εκπληκτική σε ορισμένα σημεία. Ταυτόχρονα, το Rust δεν είναι τόσο μινιμαλιστικό όσο το Go και ισχυρίζεται ότι είναι μια γλώσσα συστήματος.

Η σύνταξη του Rust είναι σε μεγάλο βαθμό δανεισμένη από τη C και τη C++, με μερικές ιδέες από τις Go, C#, Haskell, Python και Ruby. Δεν θα περιγράψω εξαντλητικά τη σύνταξη της γλώσσας, αλλά θα επικεντρωθώ μόνο στις πιο ενδιαφέρουσες έννοιες.

Η σκουριά κερδίζει δημοτικότητα, αλλά πολλοί εξακολουθούν να μην καταλαβαίνουν την αξία και τις λειτουργίες της. Θα σας πούμε για τα κύρια πλεονεκτήματα της γλώσσας προγραμματισμού Rust.

Τι κοινό έχουν το Rust και άλλες γλώσσες;

Οι παραπάνω ορισμοί είναι δύσκολο να πιστευτούν· φαίνεται σαν μια μη ρεαλιστική δήλωση, αφού προηγουμένως όλες οι γλώσσες επέλεγαν μία από τις πλευρές: αξιοπιστία ή απόδοση.

Ένας εντυπωσιακός εκπρόσωπος της υψηλής ταχύτητας είναι, αλλά όλοι γνωρίζουμε πόσο συχνά εμφανίζονται σφάλματα λόγω εσφαλμένης πρόσβασης σε εκχωρημένη μνήμη, απομακρυσμένους διακομιστές και δεν υπάρχει τίποτα να πούμε για απρόβλεπτες εξόδους των αποτελεσμάτων εργασίας. Λόγω των πολλαπλών νημάτων εγγραφής, είναι συχνά δύσκολο να προβλεφθεί το αποτέλεσμα.

Η προκατάληψη προς την αξιοπιστία αποδεικνύεται καλύτερα από τη γλώσσα Haskell, το οποίο είναι μεταγλωττισμένο στη φύση και παρέχει υψηλή απόδοση ασφάλειας. Οτιδήποτε μπορεί να μεταγλωττιστεί θα λειτουργήσει σωστά. Κύριο μειονέκτημα- πρόκειται για χαμηλή απόδοση, είναι δύσκολο να φανταστεί κανείς ένα έργο που απαιτεί υψηλή ταχύτητα εγγραφής Haskell.

Τα υπόλοιπα καταλαμβάνουν επίσης μια ουδέτερη θέση, μια ορισμένη ισορροπία. Επικεντρώνονται στην πρακτικότητα.

Σκουριάενσωματώνει τα καλύτερα χαρακτηριστικά C++Και Haskell, και ήταν επίσης σε θέση να διατηρήσει επαρκή πρακτικότητα και λειτουργικότητα από άλλους ανταγωνιστές.

Ποια είναι η ομορφιά της γλώσσας Rust;

Τα μαγικά χαρακτηριστικά του Rust διατίθενται μέσω των βασικών στοιχείων της συλλογής και των πληροφοριών οντοτήτων κατόχου ( ιδιοκτήτης), σχετικά με έναν προγραμματιστή που διορθώνει μόνο προσωρινά ή έχει αναλάβει το έργο ( μεταβλητό δάνειο), καθώς και για τον απλό θεατή ( αμετάβλητο δάνειο).

Κατά τον προγραμματισμό σε Ιάβαή C++, πρέπει να διατηρήσετε αυτές τις πληροφορίες στη μνήμη, αν και ο τύπος των δεδομένων είναι κάπως διαφορετικός. ΣΕ ΣκουριάΑυτό υλοποιείται χρησιμοποιώντας κατασκευές γλώσσας· αυτές οι πληροφορίες διευκολύνουν τον μεταγλωττιστή να καθορίσει την ταυτότητα και να επιλέξει σωστά το μοντέλο συμπεριφοράς. Με έναν μεταγλωττιστή, μπορείτε να διασφαλίσετε ότι τα πιθανά και κοινά προβλήματα εξαλείφονται κατά την εκτέλεση του κώδικα.

Αυτή η γλώσσα απαιτεί μια ελαφρώς διαφορετική προσέγγιση. Παρά το ασυνήθιστο, ο αλγόριθμος είναι αρκετά προφανής και αποτελεσματικός. Τώρα θα ορίσουμε τα βασικά της γλώσσας, τα οποία μπορούν να οδηγήσουν σε αδιέξοδο κατά την έναρξη της μελέτης:

  1. Το σύστημα κληρονομικότητας έχει εξαλειφθεί εντελώς, μια ειδική δομή και ικανότητες χρησιμοποιούνται για την αντικατάστασή του, περισσότερες λεπτομέρειες χαρακτηριστικά.
  2. Οι δείκτες υπάρχουν αποκλειστικά σε κώδικα που δεν υπόκειται σε πρόσθετη προστασία, δηλαδή μέσα στη συνάρτηση unsafe(). Για να τα αντικαταστήσει, ο ασφαλής κώδικας χρησιμοποιεί αναφορές που παρέχουν τον σωστό δείκτη σε υπάρχοντα αντικείμενα.
  3. Εάν ο σύνδεσμος είναι στατικός και οδηγεί σε ένα συγκεκριμένο στοιχείο, για παράδειγμα, αμετάβλητο δανεισμό = &Αντικείμενο , δεν μπορεί να τροποποιηθεί από κανέναν χρήστη μέχρι να πεθάνει ο σύνδεσμος.
  4. Εάν υπάρχει ένας μεταβλητός σύνδεσμος δανείου = &mut Object που αλλάζει, τα περιεχόμενα δεν μπορούν να διαβαστούν από κανέναν άλλο χρήστη για όλη τη διάρκεια ζωής του συνδέσμου.
  5. Οι προγραμματιστές επικεντρώνονται στις πλατφόρμες Mac και *nix, γι' αυτό λειτουργεί στο σύστημα Windowsείναι δυνατή μόνο χρησιμοποιώντας το περιβάλλον GNU.

Το κοινό-στόχος είναι πολύ σημαντικό· η γλώσσα Rust έχει μια αρκετά ενεργή κοινότητα, ένα ανεπτυγμένο σύστημα επικοινωνίας και εκπαίδευσης. Συνιστούμε να επισκεφτείτε το κανάλι IRC ή το Reddit. Μέχρι σήμερα έχει ήδη γραφτεί, και τα περισσότερα από αυτά εξακολουθούν να αναπτύσσονται συνεχώς, τα έργα τους μπορούν να βρεθούν στο GitHub.

Η γλώσσα είναι πιο δημοφιλής μεταξύ των προγραμματιστών που έχουν ακολουθήσει τον δρόμο της δημιουργίας γραφικών και παιχνιδιών. Υπάρχουν ακόμη και εξελίξεις για τη δημιουργία ενός πλήρους λειτουργικού συστήματος, αλλά εξακολουθούν να αναπτύσσονται. Στο εγγύς μέλλον υπάρχει η δυνατότητα συγγραφής προγραμμάτων πελατών και διακομιστών web. Όλες οι παραπάνω εργασίες εντάσσονται πλήρως στις δυνατότητες του Rust.

Το κύριο, και πιθανώς το μοναδικό, μειονέκτημα είναι η υπερβολικά ενεργή ανάπτυξή του. Καθώς κυκλοφορούν νέες εκδόσεις, η σύνταξη αλλάζει κάπως και περιοδικά υπάρχει ανάγκη αλλαγής της λογικής συμπεριφοράς και ανάπτυξης προκειμένου να προσαρμοστεί στις νέες δυνατότητες. Η κατάσταση θα συνεχιστεί για κάποιο χρονικό διάστημα μέχρι την κυκλοφορία του Rust-1.0.

Η κανονική στήλη " Αυτή την εβδομάδα στο Rust", που μπορείτε να βρείτε στο Rust "n Stuffs στον σύνδεσμο. Υπάρχουν πάντα πληροφορίες για προηγούμενες και προηγούμενες αλλαγές, καθώς και προοπτικές ανάπτυξης της γλώσσας.

Μέχρι τώρα ίσως έχετε παρατηρήσει ότι η σύνταξη της εν λόγω γλώσσας προγραμματισμού είναι πολύ παρόμοια με τη σύνταξη γλωσσών όπως η C/C++, επειδή και στις δύο περιπτώσεις χρησιμοποιούνται δύο κάθετες για την επισήμανση σχολίων, τα μπλοκ κώδικα περιβάλλονται από σγουρά άγκιστρα , και τα ορίσματα συνάρτησης περιβάλλονται από παρενθέσεις. Θυμηθείτε επίσης ότι η λέξη-κλειδί fn χρησιμοποιείται για τη δήλωση συναρτήσεων και κάθε πρόγραμμα πρέπει να έχει μια συνάρτηση main(). Το θαυμαστικό μετά το όνομα της συνάρτησης println σε αυτήν την περίπτωση υποδεικνύει ότι χρησιμοποιείται μια μακροεντολή (ουσιαστικά ένα βολικό περιτύλιγμα γύρω από τη λειτουργία εκτύπωσης από τη βιβλιοθήκη χρόνου εκτέλεσης Rust).

Για να μεταγλωττίσετε το πρόγραμμα, απλώς εκτελέστε την εντολή:

Rustc γεια σου.rs

Ως αποτέλεσμα, ένα δυαδικό αρχείο με το όνομα hello θα πρέπει να εμφανίζεται στον κατάλογο με το αρχείο πηγαίου κώδικα του προγράμματος· για να το εκτελέσετε, απλώς εκτελέστε την εντολή./hello. Αλλά αν προσέξετε το μέγεθος αυτού του αρχείου, θα σοκαριστείτε κάπως: θα ξεπεράσει τα 800 KB. Και όλα αυτά χρειάζονται για να λειτουργήσει ένα τόσο απλό πρόγραμμα; Λοιπόν, από προεπιλογή, ο μεταγλωττιστής Rust συνδέει στατικά τις περισσότερες από τις βιβλιοθήκες χρόνου εκτέλεσης με το πρόγραμμα, ώστε να μπορείτε να αντιγράψετε το δυαδικό σε ένα σύστημα που δεν έχει εγκατεστημένες τις βιβλιοθήκες χρόνου εκτέλεσης Rust και να το εκτελέσετε χωρίς προβλήματα. Ωστόσο, μπορείτε επίσης να πείτε στον μεταγλωττιστή να εκτελεί βελτιστοποιήσεις και δυναμική σύνδεση:

Rustc -O C προτιμώ-δυναμική γεια.ρσ

Τώρα θα λάβετε ένα δυαδικό αρχείο πιο αποδεκτού μεγέθους, ίσο με 8 KB, αλλά εάν χρησιμοποιήσετε το βοηθητικό πρόγραμμα ldd, θα διαπιστώσετε ότι για να λειτουργήσει σωστά το πρόγραμμα, πρέπει να υπάρχει στο σύστημα η δυναμική βιβλιοθήκη libstd.<версия>.Έτσι .

Σύνταξη γλώσσας προγραμματισμού

Τώρα που μπορούμε να μεταγλωττίσουμε και να εκτελέσουμε προγράμματα στο Rust, προτείνω να κατανοήσουμε τη σύνταξη αυτής της γλώσσας προγραμματισμού και να επισημάνουμε τις διαφορές της από τη σύνταξη γλωσσών προγραμματισμού όπως η C, η C++ και άλλες παρόμοιες:

Fn doubler (x: i32) -> i32 ( x * 2 ) fn main () ( έστω a: i32 = 5; έστω b; b = doubler(a); println!("a φορές 2 ()", b) ; αντιστοίχιση b ( 1 ... 10 => println!("Από 1 έως 10"), _ => println!("Άλλος αριθμός"), ) )

Εάν έχετε συνηθίσει να εργάζεστε με γλώσσες C/C++, μπορεί να νομίζετε ότι αυτός ο κώδικας είναι κάπως περίεργος, αλλά είναι αρκετά λογικό. Ας ξεκινήσουμε με τη συνάρτηση main(): στην πρώτη γραμμή του let δηλώνουμε μια ακέραια μεταβλητή a 32 bit και της εκχωρούμε μια αρχική τιμή 5. Θα μπορούσαμε να παραλείψουμε να καθορίσουμε τον τύπο της μεταβλητής (το i32 είναι ο τυπικός τύπος μεταβλητής) και επίσης να μην του εκχωρήσετε μια αρχική τιμή και σε αυτήν την περίπτωση θα περιέχει μηδενική τιμή. Σημειώστε ότι εάν δηλώσετε μια μεταβλητή και της εκχωρήσετε μια συγκεκριμένη τιμή με τον ίδιο τρόπο όπως η μεταβλητή a στο παράδειγμα, δεν θα μπορείτε να αλλάξετε την τιμή της αργότερα, επομένως θα δημιουργηθεί ένα μήνυμα σφάλματος κατά τη μεταγλώττιση του παρακάτω αποσπάσματος κώδικα:

Έστω a: i32 = 5; a = 10;

Από προεπιλογή, οι μεταβλητές στο Rust είναι αμετάβλητες, που σημαίνει ότι οι τιμές τους δεν μπορούν να αλλάξουν μετά την προετοιμασία. Πρέπει να δηλώσετε ρητά μεταβλητές μεταβλητές με παρόμοιο τρόπο:

Έστω mut a: i32 = 5;

Γιατί χρειάζεται αυτό; Αυτό είναι επιπλέον δουλειά, έτσι δεν είναι; Λοιπόν, στην ουσία αυτό είναι αλήθεια, αλλά, από την άλλη πλευρά, αυτό το χαρακτηριστικό της γλώσσας προγραμματισμού βοηθά στην ανάπτυξη ασφαλών προγραμμάτων. Θα πρέπει να κάνετε μεταβλητές μόνο μεταβλητές των οποίων οι τιμές πρέπει στην πραγματικότητα να αλλάξουν. Το Rust σας αναγκάζει να είστε όσο το δυνατόν πιο αναλυτικοί για να περιγράψετε όσο το δυνατόν ακριβέστερα πώς λειτουργεί το πρόγραμμα: η παραπάνω γραμμή δηλώνει μια υπογεγραμμένη ακέραια μεταβλητή a μεγέθους ακριβώς 32 bit, με δυνατότητα αλλαγής της τιμής της στο μέλλον.

Στη συνέχεια, καλούμε τη συνάρτηση διπλασιαστή με όρισμα τη μεταβλητή a και αποθηκεύουμε την τιμή επιστροφής στη μεταβλητή b. Προσέξτε τη δήλωση της συνάρτησης διπλασιαστή, η οποία βρίσκεται στην αρχή του κωδικού προγράμματος: υποδεικνύει τον τύπο της παραμέτρου συνάρτησης (i32) και τον τύπο της τιμής επιστροφής (i32) μετά τα σύμβολα ->. Είναι επίσης εύκολο να δει κανείς ότι η συνάρτηση εκτελεί μια μεμονωμένη λειτουργία, x * 2 , η οποία δεν ακολουθείται καν από ερωτηματικό, όπως ένα κανονικό μπλοκ κώδικα Rust. τι συμβαίνει εκεί?

Αποδεικνύεται ότι μπορείτε να επιστρέψετε την τιμή μιας συνάρτησης είτε με τον ίδιο τρόπο όπως στο C, είτε απλά τοποθετώντας την έκφραση στην τελευταία γραμμή του κώδικα συνάρτησης, όπως έγινε σε αυτήν την περίπτωση. Και, καθώς αυτή είναι απλώς μια έκφραση, δεν χρειάζεται να βάλετε ένα ερωτηματικό μετά από αυτήν.

Ας επιστρέψουμε στη συνάρτηση main(), όπου χρησιμοποιήσαμε τη μακροεντολή println!() για να εκτυπώσουμε το αποτέλεσμα. Σημειώστε την τεχνική της αντικατάστασης της τιμής μιας μεταβλητής χρησιμοποιώντας την ακολουθία χαρακτήρων () . Τέλος, το παράδειγμα δείχνει την εξαιρετικά χρήσιμη λέξη-κλειδί «ταιριάσματος» της γλώσσας προγραμματισμού Rust, η οποία μπορεί να μειώσει σημαντικά την ποσότητα του κώδικα εάν χρειαστεί να εκτελέσετε μεγάλο αριθμό εντολών if/else. Σε αυτήν την περίπτωση, το 1...10 είναι μια δήλωση ενός εύρους τιμών (από 1 έως και 10) και ο χαρακτήρας υπογράμμισης (_) ταιριάζει με όλες τις άλλες τιμές.

Στο Rust, ο τύπος συμβολοσειράς char επιτρέπει τη χρήση χαρακτήρων τεσσάρων byte, δηλαδή οποιωνδήποτε χαρακτήρων Unicode, και αυτό σημαίνει ότι η γλώσσα προγραμματισμού προσαρμόστηκε στο στάδιο του σχεδιασμού για να λειτουργεί με διαφορετικές γλώσσες και ειδικούς χαρακτήρες. Ένας άλλος χρήσιμος τύπος δεδομένων είναι μια πλειάδα, η οποία είναι μια συλλογή μεταβλητών διαφορετικών τύπων:

Έστω x = (1, 2.0, "Hello");

Σε αυτήν την περίπτωση, μια ακέραια τιμή, μια τιμή float και μια τιμή συμβολοσειράς τοποθετούνται στην ίδια πλειάδα. Αυτές οι τιμές είναι αμετάβλητες και μπορούν να προσπελαστούν με τον ίδιο τρόπο:

Println!("()", x.2);

Ως αποτέλεσμα, θα βγει η τιμή του τρίτου στοιχείου της πλειάδας x, δηλαδή η συμβολοσειρά "Hello" . Όπως συμβαίνει με τους κανονικούς πίνακες, οι οποίοι υποστηρίζονται επίσης στο Rust, η αρίθμηση των στοιχείων των πλειάδων ξεκινά από το μηδέν. Μπορείτε να χρησιμοποιήσετε πλειάδες για να επιστρέψετε πολλαπλές τιμές από μια συνάρτηση:

Διακόπτης Fn(είσοδος: (i32, i32)) -> (i32, i32) ( (είσοδος.1, είσοδος.0) ) fn main() (έστω x = (10, 50); έστω y = διακόπτης(x) ; println!("(), ()", y.0, y.1); )

Σε αυτήν την περίπτωση, μια συνάρτηση που ονομάζεται switch() παίρνει μια πλειάδα δύο ακέραιων τιμών 32-bit και τις αποθηκεύει στη μεταβλητή εισόδου. Επιστρέφει επίσης μια πλειάδα με δύο ακέραιες τιμές. Αυτή η συνάρτηση χρησιμοποιεί μια απλή έκφραση που σας επιτρέπει να ανταλλάξετε τα στοιχεία μιας πλειάδας και να επιστρέψετε την πλειάδα που προκύπτει.

Η συνάρτηση main() δημιουργεί μια πλειάδα με το όνομα x που περιέχει τις τιμές 10 και 50 και μια πλειάδα με το όνομα y που περιέχει τις τιμές που επιστράφηκαν από την κλήση στο switch(). Στη συνέχεια, οι τιμές της πλειάδας εμφανίζονται απλώς στην οθόνη (50, 10).

Συμβουλή:Εάν θέλετε να εξερευνήσετε μόνοι σας τις δυνατότητες του Rust, σας συνιστούμε να ξεκινήσετε διαβάζοντας την επίσημη τεκμηρίωση που βρίσκεται στη διεύθυνση https://doc.rust-lang.org/book.

Αυτή ήταν μια σύντομη περιγραφή της σύνταξης και των δυνατοτήτων της γλώσσας προγραμματισμού Rust. Εάν θέλετε να μάθετε περισσότερα για αυτήν τη γλώσσα προγραμματισμού σε μια ειδική σειρά άρθρων, ενημερώστε μας!

Συνεχίζοντας το θέμα:
μήλο

Χειριστές / 24/10/2017 υλικολογισμικό τηλεφώνου MTS (Smart Race, Sprint, Surf, Run 4G) Η MTS, όπως κάθε άλλος πάροχος, προσφέρει στους πελάτες της διάφορα μοντέλα smartphone για...

Νέα άρθρα
/
Δημοφιλής