Εκμάθηση Scala
⚡ Έξυπνη Σύνοψη
Το Scala Tutorial παρουσιάζει μια στατικά τυποποιημένη γλώσσα προγραμματισμού, βασισμένη σε JVM, η οποία συνδυάζει τον αντικειμενοστρεφή και τον λειτουργικό προγραμματισμό. Ο οδηγός καλύπτει την εγκατάσταση, τη σύνταξη, τα βασικά χαρακτηριστικά και τα πλαίσια που καθιστούν την Scala ιδανική για τη δημιουργία ταυτόχρονων, επεκτάσιμων και συνοπτικών σύγχρονων εφαρμογών.

Τι είναι το Scala;
Scala είναι μια στατικά τυποποιημένη γλώσσα προγραμματισμού που συνδυάζει αντικειμενοστρεφή και λειτουργικό προγραμματισμό για τη βελτίωση της επεκτασιμότητας των εφαρμογών. Η Scala εκτελείται κυρίως στην πλατφόρμα JVM και οι προγραμματιστές μπορούν επίσης να τη χρησιμοποιήσουν για να γράψουν λογισμικό για εγγενείς πλατφόρμες μέσω του Scala-Native ή για το πρόγραμμα περιήγησης μέσω του ScalaJs και του JavaΓραφή χρόνο εκτέλεσης.
Η Scala είναι μια επεκτάσιμη γλώσσα που χρησιμοποιείται για την ανάπτυξη λογισμικού για πολλαπλές πλατφόρμες, και από εκεί πήρε ακριβώς το όνομά της. Η γλώσσα σχεδιάστηκε για να λύσει πολλά από τα προβλήματα πολυλογίας που εντοπίζονται στο Java παραμένοντας συνοπτικός. Ο Martin Odersky σχεδίασε τη Scala και η πρώτη δημόσια κυκλοφορία της εμφανίστηκε το 2004.
Γιατί να μάθεις Scala
Ακολουθούν οι κύριοι λόγοι για να μάθετε τη γλώσσα προγραμματισμού Scala:
- Η Scala είναι εύκολη στην εκμάθηση για αντικειμενοστρεφείς προγραμματιστές και Java προγραμματιστές και έχει γίνει μια από τις δημοφιλείς γλώσσες τα τελευταία χρόνια.
- Η Scala προσφέρει λειτουργίες πρώτης κατηγορίας για τους χρήστες.
- Η Scala μπορεί να εκτελεστεί στο FMV, ανοίγοντας το δρόμο για διαλειτουργικότητα με άλλες γλώσσες.
- Έχει σχεδιαστεί για εφαρμογές που είναι ταυτόχρονες, κατανεμημένες και ανθεκτικές στην επεξεργασία μηνυμάτων, γεγονός που την καθιστά μία από τις πιο περιζήτητες γλώσσες αυτής της δεκαετίας.
- Είναι μια συνοπτική, ισχυρή γλώσσα που μπορεί να αναπτυχθεί γρήγορα ανάλογα με τις απαιτήσεις των χρηστών της.
- Είναι αντικειμενοστρεφές και περιλαμβάνει πολλά χαρακτηριστικά λειτουργικού προγραμματισμού, δίνοντας στους προγραμματιστές μεγάλη ευελιξία στον τρόπο που γράφουν κώδικα.
- Η Scala προσφέρει Duck Typing μέσω δομικών τύπων.
- Έχει λιγότερο τυποποιημένο περιεχόμενο από Java.
- Τα πλαίσια Lift and Play, τα οποία είναι γραμμένα σε Scala, συνεχίζουν να ωριμάζουν και να κερδίζουν σε δημοτικότητα.
Πώς να εγκαταστήσετε το Scala
Για να ξεκινήσετε να γράφετε προγράμματα Scala, πρέπει να το έχετε εγκατεστημένο στον υπολογιστή σας. Για να το κάνετε αυτό, επισκεφθείτε την επίσημη ιστοσελίδα στη διεύθυνση https://www.scala-lang.org/download/ για να κατεβάσετε την τελευταία έκδοση του Scala.
Ακολουθώντας τον σύνδεσμο, σας παρουσιάζονται δύο επιλογές για την εγκατάσταση του Scala. Για αυτό το σεμινάριο Scala, θα χρησιμοποιήσουμε το IntelliJ IDEA, το οποίο παρέχει εξαιρετική υποστήριξη Scala από την πρώτη στιγμή.
Μόλις επισκεφθείτε τον σύνδεσμο λήψης, θα βρείτε δύο εκδόσεις του IntelliJ IDE.
Για αυτό το σεμινάριο Scala, θα κατεβάσουμε την Έκδοση Κοινότητας, η οποία είναι δωρεάν και περιλαμβάνει όλα όσα χρειάζεστε για να γράψετε προγράμματα Scala.
Βήμα 1) Επιλέξτε Έκδοση Κοινότητας.
Στη σελίδα, κάντε κλικ στο αναπτυσσόμενο μενού στην Έκδοση Κοινότητας.
Παρουσιάζει μια επιλογή για λήψη του IntelliJ IDE μαζί με το JBR, το οποίο περιέχει μια υλοποίηση JDK (Java Κιτ Ανάπτυξης), όπως το OpenJDK, το οποίο χρειάζεται η Scala για να μεταγλωττίσει και να εκτελέσει κώδικα.
Βήμα 2) Εκτελέστε την εγκατάσταση.
Μόλις κατεβάσετε το IntelliJ, κάντε διπλό κλικ στο πρόγραμμα εγκατάστασης και ακολουθήστε τον οδηγό που εμφανίζεται στην οθόνη.
Βήμα 3) Επιλέξτε μια τοποθεσία.
Επιλέξτε μια τοποθεσία για να εγκαταστήσετε το IDE.
Εάν δεν κατεβάσατε το πακέτο με το JDK, το πρόγραμμα εγκατάστασης εξακολουθεί να σας ζητά να προσθέσετε το JDK μέσω ενός πλαισίου ελέγχου κατά την εγκατάσταση.
Βήμα 4) Κάντε κλικ στο κουμπί Επόμενο.
Αφήστε τις υπόλοιπες προεπιλογές ως έχουν και κάντε κλικ στο κουμπί Επόμενο.
Πρόγραμμα Scala Hello World
Βήμα 5) Κάντε κλικ στο εικονίδιο εκκίνησης.
Μόλις ολοκληρωθεί η εγκατάσταση, εκτελέστε το IntelliJ IDE κάνοντας κλικ στο εικονίδιο εκκίνησης στο μενού Έναρξη όπως μια κανονική εφαρμογή.
Πρέπει ακόμα να προσθέσετε το πρόσθετο Scala στο IntelliJ. Κάντε κλικ στο αναπτυσσόμενο μενού στο μενού διαμόρφωσης κάτω δεξιά στην οθόνη και επιλέξτε την επιλογή Πρόσθετα.
Στην καρτέλα Marketplace, αναζητήστε Scala. Το πρόσθετο εμφανίζεται ως το πρώτο αποτέλεσμα στην ετικέτα Γλώσσες.
Βήμα 6) Εγκαταστήστε το πρόσθετο.
Κάντε κλικ στην επιλογή Εγκατάσταση για να ξεκινήσετε τη λήψη του πρόσθετου Scala.
Βήμα 7) Επανεκκινήστε το IDE.
Αφού ολοκληρωθεί η λήψη, θα σας ζητηθεί να επανεκκινήσετε το IDE, ώστε να ξεκινήσει να λειτουργεί το εγκατεστημένο πρόσθετο.
Μετά την επανεκκίνηση, επιστρέφετε στην ίδια σελίδα όπως πριν, αλλά τώρα το πρόσθετο Scala είναι εγκατεστημένο και έτοιμο.
Βήμα 8) Επιλέξτε Δημιουργία έργου, το οποίο οδηγεί σε μια σελίδα όπου μπορείτε να επιλέξετε τη γλώσσα για το έργο.
Βήμα 9) Επιλέξτε Scala επιλέγοντας το πλαίσιο ελέγχου Scala και κάνοντας κλικ στο κουμπί Επόμενο.
Βήμα 10) Επιλέξτε μια τοποθεσία για να αποθηκεύσετε το αρχείο έργου και δώστε στο έργο ένα όνομα.
Εάν ο κατάλογος δεν υπάρχει, το IntelliJ ζητά άδεια για τη δημιουργία του φακέλου. Αποδοχή και κλικ στο Τέλος. Στη συνέχεια, θα μεταφερθείτε στο έργο Scala, το οποίο προς το παρόν δεν περιέχει κώδικα Scala.
Η φόρτωση των ευρετηρίων χρειάζεται λίγο χρόνο, οπότε μην ανησυχείτε αν δεν μπορείτε να αλληλεπιδράσετε με το IDE ενώ εμφανίζεται μια γραμμή προόδου στο κάτω μέρος. Το IDE φορτώνει τα αρχεία που απαιτούνται για την εκτέλεση του Scala και την παροχή αυτόματης συμπλήρωσης.
Βήμα 11) Κάντε κλικ στην καρτέλα Έργο στα αριστερά του IDE και αναπτύξτε την για να δείτε τα περιεχόμενα του έργου.
Σε αυτό το σημείο, το έργο είναι άδειο και περιέχει μόνο έναν φάκελο .idea και ένα αρχείο hello-world.iml που δημιουργείται από το IDE. Το σημείο ενδιαφέροντος είναι ο φάκελος src, ο οποίος περιέχει τον πηγαίο κώδικα για το έργο. Εδώ δημιουργείτε το πρώτο σας αρχείο Scala.
Βήμα 12) Κάντε δεξί κλικ στο src για να ανοίξετε ένα μενού και να δημιουργήσετε ένα νέο αρχείο Scala.
Επιλέξτε ένα όνομα για το αρχείο. Για αυτό το σεμινάριο Scala, χρησιμοποιήστε γειά σουκαι, στη συνέχεια, επιλέξτε Αντικείμενο από το αναπτυσσόμενο μενού για τον τύπο περιεχομένου του αρχείου Scala.
Μόλις το κάνετε αυτό, θα έχετε ένα αρχείο Scala που περιέχει ένα αντικείμενο singleton που θα χρησιμοποιήσετε για να εκτελέσετε τον κώδικα.
Τώρα που έχετε ένα αρχείο Scala με ένα αντικείμενο Hello, γράψτε το πρώτο σας πρόγραμμα επεκτείνοντας το αντικείμενο που δημιουργήσατε χρησιμοποιώντας τη λέξη-κλειδί App.
Η επέκταση του αντικειμένου με App υποδεικνύει στον μεταγλωττιστή ποιον κώδικα να εκτελέσει κατά την εκκίνηση του προγράμματος. Αμέσως μετά την επέκταση του App, εμφανίζεται ένα πράσινο βέλος στην αριστερή πλευρά, υποδεικνύοντας ότι το πρόγραμμα είναι πλέον εκτελέσιμο.
Μέσα στο αντικείμενο Hello, γράψτε τη συνάρτηση println() για να εκτυπώσετε το κείμενο στην κονσόλα. Εκτελέστε το πρόγραμμα κάνοντας κλικ στο πράσινο βέλος.
Κάνοντας κλικ στο βέλος, εμφανίζεται η επιλογή Run Hello. Επιλέγοντάς το, ο κώδικας μεταγλωττίζεται και μετά από λίγα δευτερόλεπτα η έξοδος του προγράμματος εμφανίζεται στην κονσόλα IntelliJ.
Έχετε πλέον εγκαταστήσει με επιτυχία το Scala και έχετε εκτελέσει το πρώτο σας πρόγραμμα.
Τι μπορείτε να κάνετε με τη Scala
Η Scala χρησιμοποιείται ευρέως σε πολλούς τομείς λόγω της ευελιξίας και της διαλειτουργικότητάς της με JVM. Συνήθεις περιπτώσεις χρήσης περιλαμβάνουν:
- Ανάπτυξη ιστοσελίδων frontend με ScalaJS.
- Ανάπτυξη για κινητά Android και iOS με Scala Native.
- Βιβλιοθήκες από την πλευρά του διακομιστή όπως HTTP4S, Akka-Http και το Play Framework.
- Εφαρμογές του Διαδικτύου των Πραγμάτων (IoT).
- Ανάπτυξη παιχνιδιών.
- Επεξεργασία φυσικής γλώσσας χρησιμοποιώντας τη σουίτα βιβλιοθηκών ScalaNLP.
- Ταυτόχρονη εξάσκηση σε προηγμένες τεχνικές όπως ο συναρτησιακός προγραμματισμός και ο αντικειμενοστρεφής προγραμματισμός.
- Εφαρμογές υψηλής ταυτόχρονης επικοινωνίας που χρησιμοποιούν ηθοποιούς, μια βιβλιοθήκη για την JVM εμπνευσμένη από την Erlang.
- Μηχανική μάθηση με βιβλιοθήκες όπως το Figaro για πιθανοτικό προγραμματισμό και το Apache Spark για επεξεργασία δεδομένων μεγάλης κλίμακας.
Ανώνυμες Λειτουργίες
Η γλώσσα Scala υποστηρίζει ανώνυμες συναρτήσεις, οι οποίες ονομάζονται επίσης συνάρτηση κυριολεκτικάΕπειδή η Scala είναι μια λειτουργική γλώσσα, οι προγραμματιστές συχνά χωρίζουν μεγάλα προβλήματα σε πολλές μικρές εργασίες και δημιουργούν πολλές συναρτήσεις. Για να γίνει αυτό εύκολο, η Scala επιτρέπει την ανάπτυξη συναρτήσεων. στιγμιότυπα χωρίς όνομαΜπορείτε να τα αντιστοιχίσετε απευθείας σε μεταβλητές ή σε ορισμούς χρησιμοποιώντας def, όπως φαίνεται στο ακόλουθο παράδειγμα Scala:
val multiplyByTwo = (n:Int) => n * 2 def multiplyByThree = (n:Int) => n * 3
Στη συνέχεια, μπορείτε να τις χρησιμοποιήσετε όπως οι κανονικές συναρτήσεις, περνώντας παραμέτρους:
multiplyByTwo(3) //6 multiplyByThree(4) //12
Αυτές οι μέθοδοι είναι χρήσιμες όταν θέλετε καθαρό και συνοπτικό κώδικα. Οι ανώνυμες συναρτήσεις είναι χρήσιμες κατά τον ορισμό μεθόδων που είναι μικρές και δεν απαιτούν πολύ κώδικα στο σώμα τους. Είναι πολύ απλές και δεν χρειάζονται κάποια τελετή για τη δημιουργία τους.
Αυτές οι μέθοδοι δεν περιορίζονται σε συναρτήσεις με ορίσματα και μπορούν να χρησιμοποιηθούν για τη δημιουργία μεθόδων που δεν δέχονται ορίσματα.
val sayHello = () => { println("hello") }
Οι περισσότερες από αυτές τις ανώνυμες συναρτήσεις χρησιμοποιούνται σε άλλα μέρη του κώδικα όπου χρειάζεστε μια γρήγορη συνάρτηση. Για αυτόν τον λόγο, αναφέρονται επίσης ως ενσωματωμένες λειτουργίεςΗ χρήση ανώνυμων συναρτήσεων είναι ένα κοινό μοτίβο που εμφανίζεται σε όλη τη βιβλιοθήκη συλλογών για την εκτέλεση γρήγορων ενεργειών σε μια συλλογή.
Για παράδειγμα, η μέθοδος φίλτρου δέχεται μια ενσωματωμένη συνάρτηση για να δημιουργήσει μια άλλη συλλογή μόνο με τα στοιχεία που πληρούν τα κριτήρια που ορίζονται στην ανώνυμη συνάρτηση.
val myList = List(1,2,3,4,5,6,7) val myEvenList = myList.filter((n: Int) => n % 2 == 0) //List(2,4,6) val myOddList = myList.filter((n:Int) => n % 2 != 0) //List(1,3,5,7)
Εδώ οι ανώνυμες συναρτήσεις ελέγχουν αν η τιμή από τη λίστα είναι περιττή ή ζυγή και επιστρέφουν το αντίστοιχο στοιχείο.
//the one checking that the value is even (n: Int) => n % 2 == 0 //the one checking that the value is odd (n:Int) => n % 2 != 0
Στη Scala, είναι επίσης δυνατή η χρήση χαρακτήρων μπαλαντέρ όπου η παράμετρος ανώνυμης συνάρτησης δεν έχει όνομα. Για παράδειγμα:
var timesTwo = (_:Int) * 2 timesTwo(5) //10
Σε αυτό το σενάριο, δεν ονομάζετε την παράμετρο. Η υπογράμμιση χρησιμοποιείται για την αναπαράστασή της.
Τεμπέλης Αξιολόγηση
Οι περισσότερες γλώσσες αξιολογούν διαδοχικά μεταβλητές και παραμέτρους συνάρτησης, τη μία μετά την άλλη. Στη Scala, η λέξη-κλειδί lazy βοηθά στην αντιμετώπιση τιμών που δεν θέλετε να αξιολογήσετε μέχρι να αναφερθείτε σε αυτές.
Μια μεταβλητή που έχει επισημανθεί ως τεμπέλης δεν αξιολογείται εκεί που ορίζεται, κάτι που είναι κοινώς γνωστό ως αξιολόγηση eager. Αξιολογείται μόνο όταν γίνεται αναφορά σε αυτήν αργότερα στον κώδικα.
Αυτό μπορεί να είναι χρήσιμο όταν η αξιολόγηση μιας τιμής θα ήταν ένας δαπανηρός υπολογισμός. Εάν η τιμή δεν είναι πάντα απαραίτητη, γλιτώνετε τον εαυτό σας από την εκτέλεση ενός δαπανηρού υπολογισμού που μπορεί να επιβραδύνει το λογισμικό καθιστώντας τη μεταβλητή αδρανή.
lazy val myExpensiveValue = expensiveComputation def runMethod() = { if(settings == true) { use(myExpensiveValue) } else { use(otherValue) } }
Αυτή δεν είναι η μόνη περίπτωση χρήσης για τις τεμπέλικες μεταβλητές. Βοηθούν επίσης στην αντιμετώπιση των κυκλικών εξαρτήσεων στον κώδικα.
Εάν η σημαία ρυθμίσεων είναι false, δεν χρειάζεται να χρησιμοποιήσετε το myExpensiveValue, το οποίο σας γλιτώνει από την εκτέλεση δαπανηρών υπολογισμών. Αυτό βοηθά να διασφαλιστεί ότι οι χρήστες έχουν μια ομαλή εμπειρία, επειδή οι πόροι δεν σπαταλώνται σε τιμές που δεν διαβάζονται ποτέ.
Η νωθρότητα βοηθά επίσης με τα ορίσματα συνάρτησης, όπου τα ορίσματα χρησιμοποιούνται μόνο όταν αναφέρονται μέσα στη συνάρτηση. Αυτή η έννοια ονομάζεται παράμετροι κλήσης κατά όνομα.
def sometimesUsedString(someValue:String, defaultValue: => String) = { if(someValue != null) { use(defaultValue) } else { use(someValue) } }
Πολλές γλώσσες χρησιμοποιούν την προσέγγιση call-by-value (κλήση κατά τιμή) για την αξιολόγηση ορισμάτων. Μια παράμετρος που διέρχεται μέσω της διαδικασίας call-by-name (κλήση κατά όνομα) αξιολογείται μόνο όταν χρειάζεται μέσα στο σώμα της συνάρτησης. Μόλις αξιολογηθεί η τιμή, αποθηκεύεται και μπορεί να επαναχρησιμοποιηθεί αργότερα χωρίς επαναξιολόγηση, μια έννοια γνωστή ως απομνημόνευση.
Τύπος συμπέρασμα
Στη Scala, δεν χρειάζεται να δηλώνετε τύπους για κάθε μεταβλητή που δημιουργείτε, επειδή ο μεταγλωττιστής της Scala μπορεί να συμπεράνει τύπους από τη δεξιά πλευρά μιας έκφρασης. Αυτό επιτρέπει στον κώδικά σας να είναι πιο συνοπτικός και σας απαλλάσσει από τη σύνταξη τυποποιημένων κειμένων όπου ο αναμενόμενος τύπος είναι προφανής.
var first:String = "Hello, " var second:String = "World" var third = first + second //the compiler infers that third is of type String
Συνάρτηση Ανώτερης Τάξης
Μια συνάρτηση ανώτερης τάξης είναι μια συνάρτηση που μπορεί να δέχεται συναρτήσεις ως ορίσματα και μπορεί να επιστρέφει μια συνάρτηση ως τύπο επιστροφής. Στη Scala, οι συναρτήσεις θεωρούνται πολίτες πρώτης κατηγορίας. Η χρήση συναρτήσεων με αυτόν τον τρόπο σάς επιτρέπει να είστε πολύ ευέλικτοι στα είδη προγραμμάτων που μπορείτε να δημιουργήσετε. Μπορείτε να δημιουργείτε συναρτήσεις δυναμικά και να τροφοδοτείτε λειτουργικότητα δυναμικά σε άλλες συναρτήσεις.
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = { myMathFunction(n) }
Στην παραπάνω συνάρτηση, περνάτε ένα Int και μια συνάρτηση που δέχεται ένα Int και επιστρέφει ένα IntΜπορείτε να περάσετε οποιαδήποτε συνάρτηση αυτής της υπογραφής. Με τον όρο υπογραφή, εννοούμε την είσοδο και την έξοδο μιας συνάρτησης. Μια υπογραφή Int => Int σημαίνει ότι μια συνάρτηση δέχεται έναν Ακέραιο Κόσμο ως είσοδο και επιστρέφει έναν Ακέραιο Κόσμο ως έξοδο.
Μια υπογραφή του () => Int σημαίνει ότι μια συνάρτηση δεν δέχεται τίποτα ως είσοδο και επιστρέφει έναν ακέραιο αριθμό ως έξοδο. Ένα παράδειγμα τέτοιας συνάρτησης είναι αυτή που παράγει έναν τυχαίο ακέραιο αριθμό.
def generateRandomInt() = { return scala.util.Random.nextInt() }
Η παραπάνω συνάρτηση έχει μια υπογραφή () => Int.
Μια συνάρτηση μπορεί επίσης να έχει μια υπογραφή () => UnitΑυτό σημαίνει ότι η συνάρτηση δεν δέχεται τίποτα και δεν επιστρέφει τύπο. Αντίθετα, η συνάρτηση μπορεί να αλλάξει κάποια κατάσταση ή να εκτελέσει μια προκαθορισμένη ενέργεια.
Αυτού του είδους οι μέθοδοι δεν ενθαρρύνονται επειδή μπορούν να λειτουργήσουν ως ένα μαύρο κουτί που επηρεάζει ένα σύστημα με άγνωστους τρόπους. Είναι επίσης πιο δύσκολο να δοκιμαστούν. Έχοντας σαφείς τύπους εισόδου και εξόδου, μπορείτε να συλλογιστείτε τι κάνει η συνάρτησή σας.
Μια συνάρτηση υψηλότερης τάξης μπορεί επίσης να επιστρέψει μια συνάρτηση. Για παράδειγμα, θα μπορούσατε να δημιουργήσετε μια μέθοδο που επιστρέφει μια συνάρτηση δύναμης, μια μέθοδο που δέχεται έναν αριθμό και του εφαρμόζει μια δύναμη.
def powerByFunction(n:Int): Int=>Int = { return (x:Int) => scala.math.pow(x,n).toInt }
Η παραπάνω συνάρτηση δέχεται έναν ακέραιο αριθμό. Ο τύπος επιστροφής της είναι μια ανώνυμη συνάρτηση που δέχεται έναν ακέραιο αριθμό. x και το χρησιμοποιεί ως όρισμα για τη δυναμοσυνάρτηση.
Κάρυ
Στη Scala, μπορείτε να μετατρέψετε μια συνάρτηση που δέχεται δύο ορίσματα σε μία που δέχεται ένα όρισμα κάθε φορά. Όταν περνάτε ένα όρισμα, το εφαρμόζετε εν μέρει και καταλήγετε με μια συνάρτηση που δέχεται το υπόλοιπο όρισμα για να ολοκληρώσει την κλήση. Η μέθοδος Currying σάς επιτρέπει να δημιουργείτε συναρτήσεις προσθέτοντας εν μέρει ορισμένα ορίσματα.
Αυτό είναι χρήσιμο για τη δυναμική δημιουργία συναρτήσεων πριν να έχετε ένα πλήρες σύνολο ορισμάτων.
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m }
Αν χρειάζεστε μια συνάρτηση που πολλαπλασιάζει με έναν συγκεκριμένο αριθμό, δεν χρειάζεται να δημιουργήσετε άλλη μέθοδο πολλαπλασιασμού. Μπορείτε να εφαρμόσετε ένα όρισμα στη συνάρτηση curried και να επαναχρησιμοποιήσετε το αποτέλεσμα:
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m } var multiplyByFive = multiplyTwoNumbers(5) _ multiplyByFive(4) //returns 20
Αντιστοίχιση μοτίβου
Η Scala διαθέτει έναν ισχυρό ενσωματωμένο μηχανισμό που σας βοηθά να ελέγξετε εάν μια μεταβλητή πληροί ορισμένα κριτήρια, όπως μια εντολή switch στο Java ή μια αλυσίδα από δηλώσεις if/else. Η γλώσσα υποστηρίζει αντιστοίχιση προτύπων, την οποία μπορείτε να χρησιμοποιήσετε για να ελέγξετε εάν μια μεταβλητή είναι συγκεκριμένου τύπου. Η αντιστοίχιση προτύπων στη Scala είναι ισχυρή και μπορεί να αποδομήσει στοιχεία που έχουν ένα unapply μέθοδος για να λάβετε τα πεδία που σας ενδιαφέρουν απευθείας από τη μεταβλητή που αντιστοιχίζεται.
Η αντιστοίχιση μοτίβων Scala παρέχει επίσης μια πιο ευχάριστη σύνταξη από μια πρόταση switch.
myItem match { case true => //do something case false => //do something else case _ => //if none of the above do this by default }
Συγκρίνετε τη μεταβλητή με ένα σύνολο επιλογών. Όταν η μεταβλητή πληροί τα κριτήρια, η παράσταση στη δεξιά πλευρά του παχιού βέλους (=>) αξιολογείται και επιστρέφει ως αποτέλεσμα της αντιστοίχισης.
Η υπογράμμιση εντοπίζει περιπτώσεις-κεφαλαία που δεν ταιριάζουν στον κώδικα, αντικατοπτρίζοντας τη συμπεριφορά της προεπιλεγμένης περίπτωσης-κεφαλαίου σε μια πρόταση switch.
class Animal(var legs:Int, var sound:String) class Furniture(var legs:Int, var color:Int, var woodType:String) myItem match { case myItem:Animal => //do something case myItem:Furniture => //do something else case _ => //unknown type, do something else }
Στον παραπάνω κώδικα, μπορείτε να εντοπίσετε τον τύπο του myItem μεταβλητή και, με βάση αυτήν, διακλαδώστε σε συγκεκριμένο κώδικα.
Η αντιστοίχιση προτύπων ελέγχει εάν η μεταβλητή ταιριάζει με κάθε περίπτωση με τη σειρά.
Η υπογράμμιση λειτουργεί ως σύμβολο κράτησης θέσης που ταιριάζει με οποιαδήποτε συνθήκη που δεν ταιριάζουν με τις άλλες δηλώσεις πεζών-κεφαλαίων. Λαμβάνετε μια μεταβλητή myItem και καλέστε το match μέθοδος.
- Ελέγξτε αν
myItemistrueκαι εκτελέστε λογική στη δεξιά πλευρά του παχιού βέλους "=>". - Χρησιμοποιήστε την υπογράμμιση για να αντιστοιχίσετε οτιδήποτε δεν ταιριάζει με καμία από τις δηλώσεις πεζών-κεφαλαίων που ορίζονται στον κώδικα.
Με τις κλάσεις περίπτωσης, μπορείτε να αποδομήσετε την κλάση σε extracπεδία t μέσα στο αντικείμενο.
Χρησιμοποιώντας το sealed λέξη-κλειδί για τον ορισμό κλάσεων, έχετε το πλεονέκτημα ότι ο μεταγλωττιστής ελέγχει εξαντλητικά τις περιπτώσεις που προσπαθείτε να αντιστοιχίσετε και σας προειδοποιεί αν ξεχάσετε να χειριστείτε μία.
Αμετάβλητο
Είναι δυνατό να δημιουργήσετε τιμές που δεν μπορούν να αλλάξουν από άλλες συναρτήσεις στη Scala χρησιμοποιώντας το val λέξη-κλειδί. Αυτό επιτυγχάνεται με Java χρησιμοποιώντας το final λέξη-κλειδί. Στη Scala, χρησιμοποιείτε ένα val κατά τη δημιουργία μιας μεταβλητής αντί για var, η οποία είναι η εναλλακτική λύση για τις μεταβλητές μεταβλητές.
Μια μεταβλητή που ορίζεται χρησιμοποιώντας το val η λέξη-κλειδί είναι μόνο για ανάγνωση, ενώ μια που ορίζεται με var μπορούν να διαβαστούν και να τροποποιηθούν αργότερα από άλλες συναρτήσεις ή από τον χρήστη στον κώδικα.
var changeableVariable = 8 changeableVariable = 10 //the compiler does not complain, and the code compiles successfully println(changeableVariable) //10 val myNumber = 7 myNumber = 4 //this will not compile
Προσπάθεια ανάθεσης τιμής σε myNumber αφού το κήρυξε ως val Εμφανίζει ένα σφάλμα κατά τη μεταγλώττιση: "επανεκχώρηση σε val".
Γιατί να χρησιμοποιήσετε το Immutability;
Η αμετάβλητη λειτουργία αποτρέπει την απροσδόκητη αλλαγή τιμών από τον κώδικα και άλλους προγραμματιστές, κάτι που θα μπορούσε να οδηγήσει σε απρόβλεπτα αποτελέσματα. Εάν οι καταναλωτές μιας τιμής χρειάζεται να την αλλάξουν, μπορούν αντ' αυτού να δημιουργήσουν ένα αντίγραφο. Με αυτόν τον τρόπο, αποτρέπονται σφάλματα που προκαλούνται από την αλλαγή της ίδιας μεταβλητής από πολλούς παράγοντες.
Μαθήματα και αντικείμενα
Τα αντικείμενα είναι οντότητες του πραγματικού κόσμου και μια κλάση είναι ένα πρότυπο που ορίζει αντικείμενα. Οι κλάσεις έχουν τόσο κατάσταση όσο και συμπεριφορές. Οι καταστάσεις είναι είτε τιμές είτε μεταβλητές. Οι συμπεριφορές είναι οι μέθοδοι στη Scala.
Η επόμενη ενότητα δείχνει πώς να ορίσετε μια κλάση, να την δημιουργήσετε και να τη χρησιμοποιήσετε στη Scala.
Εδώ είναι μια κλάση που ονομάζεται Rectangle που έχει δύο τιμές και δύο συναρτήσεις. Μπορείτε επίσης να χρησιμοποιήσετε τις παραμέτρους l και b απευθείας ως πεδία στο πρόγραμμα. Έχετε ένα αντικείμενο που έχει μια μέθοδο main και δημιουργεί την κλάση με δύο τιμές.
Παράδειγμα:
class Rectangle(l: Int, b: Int) { val length: Int = l val breadth: Int = b def getArea: Int = l * b override def toString = s"This is a rectangle with length $length and breadth $breadth" } object RectObject { def main(args: Array[String]) { val rect = new Rectangle(4, 5) println(rect.toString) println(rect.getArea) } }
Όλα τα πεδία και οι μέθοδοι είναι δημόσια από προεπιλογή στη Scala. Είναι απαραίτητο να χρησιμοποιήσετε override επειδή toString είναι ήδη ορισμένο για κάθε αντικείμενο στη Scala.
Κληρονομία
Η Scala έχει πολλαπλούς τύπους κληρονομικότητας (μονό, πολυεπίπεδο, πολλαπλό, ιεραρχικό και υβριδικό) που μοιράζονται πολλά κοινά με τις παραδοσιακές μορφές που συναντώνται στο JavaΜπορείτε να κληρονομήσετε τόσο από κλάσεις όσο και από χαρακτηριστικά. Κληρονομείτε τα μέλη μιας κλάσης σε μια άλλη κλάση χρησιμοποιώντας τη λέξη-κλειδί extendsΑυτό επιτρέπει την επαναχρησιμοποίηση.
Είναι δυνατή η κληρονομικότητα από μία ή περισσότερες κλάσεις. Είναι επίσης δυνατή η κληρονομικότητα από υποκλάσεις που οι ίδιες έχουν τις δικές τους υπερκλάσεις, δημιουργώντας μια ιεραρχία κληρονομικότητας στη διαδικασία.
Στο παράδειγμα Scala παρακάτω, η βασική κλάση είναι Circle, και η παράγωγη κλάση είναι SphereΈνας κύκλος έχει μια τιμή που ονομάζεται ακτίνα, η οποία κληρονομείται στην κλάση Sphere. Η μέθοδος calcArea παρακάμπτεται χρησιμοποιώντας τη λέξη-κλειδί override.
Παράδειγμα:
class Circle { val radius = 5 def calcArea = { println(radius * radius) } } class Sphere extends Circle { override def calcArea = { println(radius * radius * radius) } } object SphereObject { def main(args : Array[String]) { new Sphere().calcArea } }
Abstracσμού
Στη Scala, μπορείτε να δημιουργήσετε κοιλιακούςtracΜέθοδοι t και πεδία μελών που χρησιμοποιούν abstracκλάσεις και χαρακτηριστικά t. Εσωτερικοί κοιλιακοίtracκλάσεις και χαρακτηριστικά t, μπορείτε να ορίσετε τα κοιλιακάtracπεδία t χωρίς να τα υλοποιήσουμε.
Παράδειγμα:
trait MakesSound { var nameOfSound:String def sound():String } abstract class HasLegs(var legs:Int) { val creatureName:String def printLegs():String = { return s"$creatureName has this number of legs: $legs" } }
Αυτά τα πεδία υλοποιούνται από τις κλάσεις που επεκτείνουν το χαρακτηριστικό ή το abs.tracκλάση t. Μπορείτε να χρησιμοποιήσετε χαρακτηριστικά για να δημιουργήσετε contracts για το τι πρέπει να κάνει μια εφαρμογή και στη συνέχεια να εφαρμόσει αυτές τις μεθόδους αργότερα.
trait DatabaseService { def addItemName(itemName:String) def removeItem(itemId:Int) def updateItem(itemId:Int, newItemName:String) }
Με αυτόν τον τρόπο, μπορείτε να σχεδιάσετε πώς θα φαίνεται μια εφαρμογή χωρίς να εφαρμόσετε τις μεθόδους, helping φαντάζεστε πώς θα εμφανιστούν διάφορες μέθοδοι. Ακολουθεί ένα μοτίβο γνωστό ως προγραμματισμός κοιλιακώνtracπαρά στην πραγματική εφαρμογή.
Μια τάξη που προλογίζεται με το abstract Η λέξη-κλειδί μπορεί να περιέχει και τα δύο abstract και μη κοιλιακούςtract μέθοδοι. Ωστόσο, η πολλαπλή κληρονομικότητα δεν υποστηρίζεται σε abstracμαθήματα t, ώστε να μπορείτε να επεκτείνετε μόνο έναν κοιλιακόtracτάξη τ.
Αντικείμενα Singleton
Ένα singleton είναι μια κλάση που δημιουργείται μόνο μία φορά σε ένα πρόγραμμα. Προέρχεται από ένα δημοφιλές και χρήσιμο μοτίβο προγραμματισμού γνωστό ως «πρότυπο singleton». Είναι χρήσιμο για τη δημιουργία στιγμιότυπων που προορίζονται να είναι μακράς διαρκείας και να είναι εύκολα προσβάσιμα σε όλο το πρόγραμμα, όπου η κατάσταση είναι αναπόσπαστο κομμάτι του συντονισμού των συμβάντων σε ένα σύστημα. Η δημιουργία μιας τέτοιας κλάσης στη Scala είναι εύκολη επειδή η Scala παρέχει έναν απλό τρόπο δημιουργίας singleton χρησιμοποιώντας το object λέξη-κλειδί.
object UserProfile { var userName = "" var isLoggedIn:Boolean = false }
Στη συνέχεια, μπορείτε να αναφέρετε αυτό το αντικείμενο σε όλο το πρόγραμμα με την εγγύηση ότι όλα τα μέρη του προγράμματος βλέπουν τα ίδια δεδομένα επειδή υπάρχει μόνο μία παρουσία του.
def getLoggedInStatus():Boolean = { return UserProfile.isLoggedIn } def changeLoggedInStatus():Boolean = { UserProfile.isLoggedIn = !UserProfile.isLoggedIn return UserProfile.isLoggedIn }
Η έννοια των στατικών μελών δεν υπάρχει στη Scala, γι' αυτό και χρησιμοποιούνται αντικείμενα singleton που λειτουργούν σαν στατικά μέλη μιας κλάσης.
Τάξεις σιωπηρών
Οι έμμεσες κλάσεις είναι μια δυνατότητα που προστέθηκε στην έκδοση 2.10 και χρησιμοποιούνται κυρίως για την προσθήκη νέων λειτουργιών σε υπάρχουσες κλειστές κλάσεις.
The implicit Η λέξη-κλειδί θα πρέπει να ορίζεται σε μια κλάση, αντικείμενο ή χαρακτηριστικό. Ο κύριος κατασκευαστής μιας έμμεσης κλάσης πρέπει να έχει ακριβώς ένα όρισμα στην πρώτη λίστα παραμέτρων του. Μπορεί επίσης να περιλαμβάνει μια πρόσθετη έμμεση λίστα παραμέτρων.
Στο παράδειγμα Scala παρακάτω, προστίθεται νέα λειτουργικότητα για την αντικατάσταση των φωνηέντων μιας συμβολοσειράς με *.
object StringUtil { implicit class StringEnhancer(str: String) { def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*") } }
Πρέπει να εισαγάγετε την έμμεση κλάση στην κλάση όπου τη χρησιμοποιείτε.
import StringUtil.StringEnhancer object ImplicitEx extends App { val msg = "This is Guru99!" println(msg.replaceVowelWithStar) }
Αντικειμενοστρεφής Προγραμματισμός (OOP) έναντι Συναρτησιακού Προγραμματισμού (FP)
Στο OOP, τα προγράμματα κατασκευάζονται κατά ομάδεςping δεδομένα και τις συναρτήσεις που λειτουργούν με αυτά τα δεδομένα σε μονάδες με υψηλή συνδεσιμότητα. Τα αντικείμενα μεταφέρουν τα δεδομένα τους σε πεδία και οι μέθοδοι λειτουργούν με αυτά. Σε αυτό το στυλ προγραμματισμού, το κύριο abstracΗ έννοια είναι τα δεδομένα, επειδή οι μέθοδοι που δημιουργούνται προορίζονται να λειτουργούν με βάση τα δεδομένα.
Λειτουργικός προγραμματισμός, από την άλλη πλευρά, διαχωρίζει τα δεδομένα και τις συναρτήσεις που λειτουργούν σε αυτά. Αυτό επιτρέπει στους προγραμματιστές να αντιμετωπίζουν τις συναρτήσεις ως το απόλυτοtracση και κινητήρια δύναμη κατά τη μοντελοποίηση προγραμμάτων.
Η Scala επιτρέπει τον συναρτησιακό προγραμματισμό αντιμετωπίζοντας τις συναρτήσεις ως πολίτες πρώτης κατηγορίας, επιτρέποντάς τους να μεταβιβάζονται ως τιμές σε άλλες συναρτήσεις και να επιστρέφονται επίσης ως τιμές. Ο συνδυασμός αυτών των δύο παραδειγμάτων έχει καταστήσει την Scala μια εξαιρετική επιλογή για την κατασκευή σύνθετου λογισμικού σε κλάδους όπως η επιστήμη δεδομένων.
Σημαντικά πλαίσια στο Scala
Ακολουθούν ορισμένα σημαντικά frameworks για τη Scala:
- Δοκιμάστε να παίξετε είναι ένα πλαίσιο εφαρμογών ιστού ανοιχτού κώδικα που χρησιμοποιεί Αρχιτεκτονική MVCΚυκλοφόρησε το 2007 και τώρα διατίθεται με άδεια χρήσης Apache, και έγινε ένα από τα πιο δημοφιλή frameworks στο GitHub μέχρι το 2013. Εταιρείες όπως το LinkedIn, Walmart, η Samsung και η Eero χρησιμοποιούν αυτό το πλαίσιο.
- Ανύψωση είναι ένα άλλο δωρεάν πλαίσιο ιστού γραμμένο σε Scala, που κυκλοφόρησε το 2007. Το Foursquare χρησιμοποιεί το πλαίσιο Lift. Είναι ένα πλαίσιο υψηλής απόδοσης με γρήγορο σχεδιασμό.
- Ακκά παρέχει ένα κιτ εργαλείων για τη δημιουργία εξαιρετικά ταυτόχρονων, κατανεμημένων και ανθεκτικών εφαρμογών που βασίζονται σε μηνύματα στο JVM.
- Γάτες είναι μια βιβλιοθήκη που παρέχει κοιλιακούςtracστάσεις για λειτουργικό προγραμματισμό.
- Spark είναι μια ενοποιημένη μηχανή ανάλυσης για επεξεργασία δεδομένων μεγάλης κλίμακας, που χρησιμοποιείται ευρέως σε ροές εργασίας μεγάλων δεδομένων και μηχανικής μάθησης.
Υποστήριξη συγχρονισμού
- Οι τιμές στο Scala είναι αμετάβλητες από προεπιλογή, γεγονός που το καθιστά πολύ προσαρμόσιμο σε ταυτόχρονα περιβάλλοντα.
- Η Scala διαθέτει πολλά χαρακτηριστικά που την καθιστούν ιδανική για ταυτόχρονες εφαρμογές.
- Τα Futures και Promises διευκολύνουν την ασύγχρονη επεξεργασία δεδομένων, υποστηρίζοντας έτσι τον παραλληλισμό.
- Το Akka είναι ένα κιτ εργαλείων που χρησιμοποιεί το μοντέλο ταυτόχρονης δράσης (Actor concurrency). Οι δράστες ενεργούν όταν λαμβάνουν μηνύματα.
- Συγχρονισμός με χρήση νημάτων από Java υποστηρίζεται επίσης στη Scala.
- Η επεξεργασία ροής είναι ένα άλλο εξαιρετικό χαρακτηριστικό που επιτρέπει τη συνεχή επεξεργασία δεδομένων σε πραγματικό χρόνο.
Η Scala διαθέτει μερικές από τις καλύτερες βιβλιοθήκες ταυτόχρονης χρήσης Java οικοσύστημα:
- Native Java νήματα.
- Ίνες από βιβλιοθήκες όπως η Vertx.
- ZIO, μια βιβλιοθήκη που έχει πρωτόγονα για να βοηθήσει στην αντιμετώπιση του ταυτόχρονου και ασύγχρονου υπολογισμού.
- Μνήμη Συναλλαγών Λογισμικού (STM) για συναλλαγές.
- Το Future, το οποίο είναι ενσωματωμένο στη γλώσσα Scala.
Java εναντίον Σκάλας
Εδώ είναι τα κύρια διαφορές μεταξύ Java και τη Σκάλα.
| Scala | Java |
|---|---|
| Πιο συμπαγές και περιεκτικό. | Συγκριτικά μεγαλύτερα κομμάτια κώδικα. |
| Σχεδιασμένο και αναπτυγμένο ώστε να είναι αντικειμενοστρεφές και λειτουργικό. Υποστηρίζει μια μεγάλη ποικιλία λειτουργικών χαρακτηριστικών προγραμματισμού, όπως η ταυτόχρονη χρήση και η αμετάβλητη λειτουργία. | Αρχικά αναπτύχθηκε ως αντικειμενοστρεφής γλώσσα και άρχισε να υποστηρίζει λειτουργίες συναρτησιακού προγραμματισμού σε πρόσφατες εκδόσεις. Δεν είναι ακόμα τόσο ισχυρή όσο η Scala για συναρτησιακό προγραμματισμό. |
| Χρησιμοποιεί το μοντέλο δράστη για την υποστήριξη της ταυτόχρονης λειτουργίας. | Χρησιμοποιεί το συμβατικό μοντέλο που βασίζεται σε νήματα για ταυτόχρονη χρήση. |
| Υποστηρίζει πλαίσια όπως το Play και το Lift. | Υποστηρίζει την Άνοιξη, τα Δισκοπότηρα και πολλά άλλα. |
| Υποστηρίζει την αργή αξιολόγηση. | Δεν υποστηρίζει εγγενώς την αργή αξιολόγηση. |
| Χωρίς στατικά μέλη. | Περιέχει στατικά μέλη. |
| Υποστηρίζει την υπερφόρτωση του χειριστή. | Δεν υποστηρίζει υπερφόρτωση χειριστή. |
| Η μεταγλώττιση του πηγαίου κώδικα είναι συγκριτικά αργή. | Η μεταγλώττιση του πηγαίου κώδικα είναι ταχύτερη από τη Scala. |
| Τα χαρακτηριστικά λειτουργούν σαν Java 8 διεπαφές. | Java 8 διεπαφές προσπαθούν να γεφυρώσουν το χάσμα μεταξύ κλάσεων και διεπαφών. |
| Η επανεγγραφή είναι μερικές φορές απαραίτητη κατά την αναβάθμιση εκδόσεων. | Γενικά, δεν απαιτείται επανεγγραφή μεταξύ των εκδόσεων. |
| Η ασφάλεια τύπων παρέχει ισχυρή αξιοπιστία κώδικα, αλλά δεν εγγυάται απόλυτη απουσία σφαλμάτων. | Ισχυρός στατικός τύποςping βοηθά στη μείωση πολλών ελαττωμάτων χρόνου εκτέλεσης. |
| Έχει ορισμένα όρια συμβατότητας με παλαιότερες εκδόσεις σε όλες τις κύριες εκδόσεις. | Ισχυρή μακροπρόθεσμη συμβατότητα με παλαιότερες εκδόσεις. |
| OperaΟι tors αντιμετωπίζονται ως κλήσεις μεθόδων. | OperaΟι tors είναι ειδική σύνταξη και δεν είναι κλήσεις μεθόδων. |
| Υποστηρίζει πολλαπλή κληρονομικότητα χρησιμοποιώντας χαρακτηριστικά. | Δεν υποστηρίζει πολλαπλή κληρονομικότητα χρησιμοποιώντας κλάσεις· χρησιμοποιεί αντ' αυτού διεπαφές. |
| Code είναι γραμμένο σε συμπυκνωμένη μορφή. | Code είναι γραμμένο σε πιο περιεκτική μορφή. |
| Το Scala δεν περιέχει τη στατική λέξη-κλειδί. | Java περιέχει τη στατική λέξη-κλειδί. |






















