diff --git a/el-gr/rust-gr.html.markdown b/el-gr/rust-gr.html.markdown new file mode 100644 index 00000000..79f210ac --- /dev/null +++ b/el-gr/rust-gr.html.markdown @@ -0,0 +1,339 @@ +--- +language: Rust +contributors: + - ["P1start", "http://p1start.github.io/"] + - ["Dimitri Kokkonis", "https://github.com/kokkonisd"] +filename: learnrust-gr.rs +lang: el-gr +--- + +_[ΣτΜ.: οι όροι "χαμηλό/υψηλό επίπεδο" αναφέρονται στην εγγύτητα μιας γλώσσας προγραμματισμού ή γενικότερα ενός +στοιχείου στην "μηχανή", ή το υλικό του υπολογιστή. Για παράδειγμα, η φράση "η C είναι μια γλώσσα χαμηλού επιπέδου" +αναφέρεται στο γεγονός ότι η C επιτρέπει άμεση και λεπτομερή διαχείρηση μνήμης, και πιο άμεσο έλεγχο του επεξεργαστή· +σε καμία περίπτωση δεν σημαίνει ότι η C έχει λιγότερες δυνατότητες, και γενικότερα δεν φέρει αρνητική σημασία.]_ + +Η Rust είναι μια γλώσσα προγραμματισμού ανεπτυγμένη από την Mozilla Research. +Συνδυάζει τον έλεγχο της απόδοσης χαμηλού επιπέδου με διευκολύνσεις και ασφάλεια υψηλού επιπέδου. + +Πετυχαίνει αυτούς τους στόχους χωρίς να χρειάζεται garbage collector ή runtime, το οποίο καθιστά δυνατή τη χρήση +βιβλιοθηκών της Rust ως αντικατάσταση της C. + +Η έκδοση 0.1 (η πρώτη της Rust) δημοσιεύθηκε τον Ιανουάριο του 2012, και για τα επόμενα 3 χρόνια η ανάπτυξή της +εξελίχθηκε τόσο γρήγορα που, μέχρι πρότινος, προτείνονταν η χρήση μη-σταθερών εκδόσεων (nightly builds) αντί σταθερών +εκδόσεων. + +Τις 15 Μαΐου 2015 δημοσιεύτηκε η εκδοχή 1.0 της Rust, με πλήρη εγγύηση συμβατότητας με προηγούμενες εκδοχές. Οι +μη-σταθερές εκδόσεις συνήθως περιλαμβάνουν γρηγορότερους χρόνους μεταγλώττισης και γενικότερες βελτιώσεις όσον αφορά +τον μεταγλωττιστή. Η μέθοδος [train release](https://www.plutora.com/blog/agile-release-train) χρησιμοποιείται, με +συστηματικές εκδόσεις να δημοσιεύονται κάθε έξι εβδομάδες. Η beta έκδοση της Rust 1.1 δημοσιεύθηκε ταυτοχρόνως με την +σταθερή έκδοση 1.0. + +Αν και η Rust είναι μια γλώσσα σχετικά χαμηλού επιπέδου, ο σχεδιασμός της περιλαμβάνει κάποιες έννοιες που συναντώνται +συνχότερα σε γλώσσες υψηλού επιπέδου. Αυτό καθιστά την Rust γρήγορη και αποδοτική αλλά επίσης εύκολη και προσβάσιμη. + + +```rust +// Αυτό είναι ένα σχόλιο. Τα σχόλια μίας γραμμής γράφονται έτσι... +// Και επεκτείνονται σε περισσότερες από μία γραμμές έτσι. + +/// Τα σχόλια documentation γράφονται έτσι, και υποστηρίζουν markdown. +/// # Παράδειγμα +/// +/// ``` +/// let five = 5 +/// ``` + +////////////////////// +// 1. Βασικές αρχές // +////////////////////// + +#[allow(dead_code)] +// Συναρτήσεις +// `i32` είναι ο τύπος που αντιστοιχεί στους 32-bit signed ακέραιους +fn add2(x: i32, y: i32) -> i32 { + // Έμεσα εννοούμενη επιστροφή του αποτελέσματος, χωρίς semicolon (;) + x + y +} + +#[allow(unused_variables)] +#[allow(unused_assignments)] +#[allow(dead_code)] +// Συνάρτηση main +fn main() { + // Αριθμοί // + + // Αμετάβλητη σύνδεση + let x: i32 = 1; + + // Καταλήξεις integer/float + let y: i32 = 13i32; + let f: f64 = 1.3f64; + + // Εξακρίβωση τύπου (type inference) + // Τις περισσότερες φορες ο μεταγλωττιστής της Rust μπορεί να εξακριβώσει τον τύπο μιας μεταβλητής, επομένως δεν + // χρειάζεται ο προγραμματιστής να τον δηλώνει ρητά. + // Σε αυτό το tutorial, οι τύποι δηλώνονται ρητά σε διάφορα σημεία, αλλά μόνο προκειμένου να είναι πιο ευανάγνωστος + // ο κώδικας. Ο μεταγλωττιστής μπορεί να το διαχειριστεί αυτόματα στις περισσότερες περιπτώσεις. + let implicit_x = 1; + let implicit_f = 1.3; + + // Πράξεις + let sum = x + y + 13; + + // Μη-αμετάβλητη αξία (με την έννοια ότι μπορεί να αλλάξει) + let mut mutable = 1; + mutable = 4; + mutable += 2; + + // Αλφαριθμητικά // + + // Σταθερά αλφαριθμητικά + let x: &str = "καλημέρα κόσμε!"; + + // Εκτύπωση αλφαριθμητικών + println!("{} {}", f, x); // 1.3 καλημέρα κόσμε! + + // A `String` – a heap-allocated string + let s: String = "καλημέρα κόσμε".to_string(); + + // Ένα κομμάτι αλφαριθμητικού (string slice) – μια μη-μεταβλητή οπτική γωνία προς ένα άλλο αλφαριθμητικό + // Το αλφαριθμητικό μπορεί να είναι στατικό όπως τα σταθερά αλφαριθμητικά, ή να περιλαμβάνεται σε ένα άλλο, + // δυναμικό αντικείμενο (σε αυτή την περίπτωση τη μεταβλητή `s`) + let s_slice: &str = &s; + + println!("{} {}", s, s_slice); // καλημέρα κόσμε καλημέρα κόσμε + + // Διανύσματα/πίνακες // + + // Πίνακας σταθερού μεγέθους + let four_ints: [i32; 4] = [1, 2, 3, 4]; + + // Δυναμικός πίνακας (διάνυσμα) + let mut vector: Vec = vec![1, 2, 3, 4]; + vector.push(5); + + // Ένα κομμάτι – μια μη-μεταβλητή οπτική γωνία προς ένα διάνυσμα ή πίνακα + // Είναι παρόμοιο με το κομμάτι αλφαριθμητικού που είδαμε προηγουμένως + let slice: &[i32] = &vector; + + // Μπορούμε να χρησιμοποιήσουμε το `{:?}` για να εκτυπώσουμε κάτι σε στυλ debug + println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] + + // Tuples (πλειάδες) // + + // Ένα tuple είναι μια σταθερού μεγέθους σειρά από αξίες (πιθανά διαφορετικού τύπου) + let x: (i32, &str, f64) = (1, "καλημέρα", 3.4); + + // Μπορούμε να χρησιμοποιήσουμε το `let` και ένα tuple για να δώσουμε πολλές αξίες σε πολλές μεταβλητές ταυτόχρονα + // (destructuring `let`) + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 καλημέρα 3.4 + + // Μπορούμε επίσης να επιλέξουμε ένα συγκεκριμένο στοιχείο από ένα tuple + println!("{}", x.1); // καλημέρα + + ////////////// + // 2. Τύποι // + ////////////// + + // Δομή + struct Point { + x: i32, + y: i32, + } + + let origin: Point = Point { x: 0, y: 0 }; + + // Μια δομή με ανώνυμα πεδία, ή αλλιώς μια `δομή tuple` (`tuple struct`) + struct Point2(i32, i32); + + let origin2 = Point2(0, 0); + + // Enum, όπως στην C + enum Direction { + Left, + Right, + Up, + Down, + } + + let up = Direction::Up; + + // Enum με πεδία + enum OptionalI32 { + AnI32(i32), + Nothing, + } + + let two: OptionalI32 = OptionalI32::AnI32(2); + let nothing = OptionalI32::Nothing; + + // Γενικότητα (genericity) // + + struct Foo { bar: T } + + // Αυτό ορίζεται στην standard library ως `Option` + enum Optional { + SomeVal(T), + NoVal, + } + + // Μέθοδοι // + + impl Foo { + // Οι μέθοδοι παίρνουν πάντα μια ρητή παράμετρο `self` + fn bar(&self) -> &T { // Δανειζόμαστε το self + &self.bar + } + fn bar_mut(&mut self) -> &mut T { // Δανειζόμαστε το self ως μη-αμετάβλητη αξία + &mut self.bar + } + fn into_bar(self) -> T { // Εδώ το self καταναλώνεται + self.bar + } + } + + let a_foo = Foo { bar: 1 }; + println!("{}", a_foo.bar()); // 1 + + // Χαρακτηρηστικά (traits) (γνωστά ως interfaces ή typeclasses σε άλλες γλώσσες) // + + trait Frobnicate { + fn frobnicate(self) -> Option; + } + + impl Frobnicate for Foo { + fn frobnicate(self) -> Option { + Some(self.bar) + } + } + + let another_foo = Foo { bar: 1 }; + println!("{:?}", another_foo.frobnicate()); // Some(1) + + ////////////////////////////////////////////////// + // 3. Αντιστοιχίσεις Μοτίβων (Pattern Matching) // + ////////////////////////////////////////////////// + + let foo = OptionalI32::AnI32(1); + match foo { + OptionalI32::AnI32(n) => println!("Είναι ένα i32: {}", n), + OptionalI32::Nothing => println!("Δεν είναι τίποτα!"), + } + + // Προχωρημένο pattern matching + struct FooBar { x: i32, y: OptionalI32 } + let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) }; + + match bar { + FooBar { x: 0, y: OptionalI32::AnI32(0) } => + println!("Οι αριθμοί είναι μηδέν!"), + FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m => + println!("Οι αριθμοί είναι οι ίδιοι"), + FooBar { x: n, y: OptionalI32::AnI32(m) } => + println!("Διαφορετικοί αριθμοί: {} {}", n, m), + FooBar { x: _, y: OptionalI32::Nothing } => + println!("Ο δεύτερος αριθμός δεν είναι τίποτα!"), + } + + ///////////////////// + // 4. Έλεγχος ροής // + ///////////////////// + + // Βρόγχοι `for` + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Διαστήματα + for i in 0u32..10 { + print!("{} ", i); + } + println!(""); + // Τυπώνει `0 1 2 3 4 5 6 7 8 9 ` + + // Βρόγχοι `if` + if 1 == 1 { + println!("Τα μαθηματικά δουλεύουν!"); + } else { + println!("Ωχ όχι..."); + } + + // `if` ως έκφραση + let value = if true { + "καλό" + } else { + "κακό" + }; + + // Βρόγχοι `while` + while 1 == 1 { + println!("Το σύμπαν λειτουργεί κανονικά."); + // Μπορούμε να βγούμε από το βρόγχο με το `break` + break + } + + // Ατέρμονος βρόχγος + loop { + println!("Καλημέρα!"); + // Μπορούμε να βγούμε από το βρόγχο με το `break` + break + } + + ////////////////////////////////// + // 5. Ασφάλεια μνήμης & δείκτες // + ////////////////////////////////// + + // Δείκτης με ιδιοκτήτη – μόνο ένα αντικείμενο μπορεί να είναι ο "ιδιοκτήτης" αυτού του δείκτη ανά πάσα στιγμή + // Αυτό σημαίνει ότι μόλις το `Box` βγει εκτός πλαισίου (out of scope), ο δείκτης μπορεί να ελευθερωθεί με ασφάλεια + let mut mine: Box = Box::new(3); + *mine = 5; // Dereference του δείκτη + // Εδώ, το `now_its_mine` γίνεται ιδιοκτήτης του `mine`. Δηλαδή, το `mine` μετακινείται. + let mut now_its_mine = mine; + *now_its_mine += 2; + + println!("{}", now_its_mine); // 7 + // println!("{}", mine); // Αυτό παράγει λάθος κατά τη μεταγλώττιση διότι τώρα ο δείκτης ανοίκει στο `now_its_mine` + + // Reference (αναφορά) – ένας αμετάβλητος δείκτης που αναφέρεται σε άλλα δεδομένα + // Όταν μια αναφορά δίνεται σε μια αξία, λέμε πως η αξία έχει "δανειστεί". + // Όταν μια αξία δανείζεται αμετάβλητα, δεν μπορεί να είναι mutated (να μεταβληθεί) ή να μετακινηθεί. + // Ένας "δανεισμός" παραμένει ενεργός μέχρι την τελευταία χρήση της μεταβλητής που δανείζεται. + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // Αντίθετα με το `mine` προηγουμένως, η μεταβλητή `var` μπορεί ακόμα να χρησιμοποιηθεί + println!("{}", *ref_var); + // var = 5; // Αυτό παράγει λάθος κατά τη μεταγλώττιση γιατί η μεταβλητή `var` είναι δανεισμένη + // *ref_var = 6; // Το ίδιο εδώ, γιατί η `ref_var` αποτελεί αμετάβλητη αναφορά + ref_var; // Εντολή no-op (τίποτα δεν εκτελείται από τον επεξεργαστή), η οποία όμως μετράει ως χρήση και κρατά τον + // "δανεισμό" ενεργό + var = 2; // Η `ref_var` δεν χρησιμοποιείται από εδώ και στο εξής, άρα ο "δανεισμός" τελειώνει + + // Μεταβλητή αναφορά + // Όσο μια αξία είναι μεταβλητά δανεισμένη, παραμένει τελείως απροσβάσιμη. + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + *ref_var2 += 2; // Ο αστερίσκος (*) χρησιμοποιείται ως δείκτης προς την μεταβλητά δανεισμένη `var2` + + println!("{}", *ref_var2); // 6 , // Αν είχαμε `var2` εδώ θα προκαλούνταν λάθος μεταγλώττισης. + // O τύπος της `ref_var2` είναι &mut i32, άρα αποθηκεύει μια αναφορά προς μια αξία i32, όχι την αξία την ίδια. + // var2 = 2; // Λάθος μεταγλώττισης, γιατί η `var2` είναι δανεισμένη. + ref_var2; // Εντολή no-op (τίποτα δεν εκτελείται από τον επεξεργαστή), η οποία όμως μετράει ως χρήση και κρατά τον + // "δανεισμό" ενεργό +} +``` + +## Μάθετε περισσότερα + +Υπάρχουν πολλά ακόμα πράγματα να μάθει κανείς· αυτά είναι μόνο τα βασικά της Rust, που επιτρέπουν να καταλάβουμε το +βασικό τρόπο λειτουργίας της. Για να μάθετε περισσότερα για τη Rust, διαβάστε το [The Rust Programming +Language](http://doc.rust-lang.org/book/index.html) και επισκεφθείτε το subreddit [/r/rust](http://reddit.com/r/rust). +Οι άνθρωποι πίσω από το κανάλι #rust στο irc.mozilla.org είναι επίσης πάντα πρόθυμοι να βοηθήσουν τους αρχάριους. + +Μπορείτε επίσης να παίξετε με τη Rust χρησιμοποιώντας τους εξής online μεταγλωττιστές: + +- [Rust playpen](http://play.rust-lang.org) +- [Rust website](http://rust-lang.org)