Scala tutorial
⚡ Smart opsummering
Scala Tutorial introducerer et statisk typebaseret, JVM-baseret programmeringssprog, der forener objektorienteret og funktionel programmering. Guiden dækker installation, syntaks, kernefunktioner og frameworks, der gør Scala ideel til at bygge samtidige, skalerbare og præcise moderne applikationer.

Hvad er Scala?
Scala er et statisk typebestemt programmeringssprog, der kombinerer objektorienteret og funktionel programmering for at forbedre skalerbarheden af applikationer. Scala kører primært på JVM-platformen, og udviklere kan også bruge det til at skrive software til native platforme via Scala-Native eller til browseren via ScalaJs og JavaScript driftstid.
Scala er et skalerbart sprog, der bruges til at bygge software til flere platforme, hvilket er præcis, hvorfor det fik sit navn. Sproget blev designet til at løse flere af de detaljerede problemer, der findes i Java samtidig med at den forblev kortfattet. Martin Odersky designede Scala, og den første offentlige udgivelse udkom i 2004.
Hvorfor lære Scala
Her er de primære grunde til at lære programmeringssproget Scala:
- Scala er let at lære for objektorienterede programmører og Java udviklere, og det er blevet et af de populære sprog i de senere år.
- Scala tilbyder førsteklasses funktioner til brugerne.
- Scala kan udføres på FMV, hvilket baner vejen for interoperabilitet med andre sprog.
- Det er designet til applikationer, der er samtidige, distribuerede og robuste meddelelsesdrevne, hvilket gør det til et af de mest efterspurgte sprog i dette årti.
- Det er et præcist og kraftfuldt sprog, der hurtigt kan vokse i takt med brugernes behov.
- Det er objektorienteret og inkluderer mange funktionelle programmeringsfunktioner, hvilket giver udviklere stor fleksibilitet i, hvordan de skriver kode.
- Scala tilbyder Duck Typing gennem strukturelle typer.
- Den har mindre standard end Java.
- Frameworksene Lift and Play, som er skrevet i Scala, fortsætter med at modnes og vokse i popularitet.
Sådan installeres Scala
For at begynde at skrive Scala-programmer skal du have det installeret på din computer. For at gøre dette skal du besøge den officielle hjemmeside på https://www.scala-lang.org/download/ for at downloade den nyeste version af Scala.
Når du følger linket, får du to muligheder for at installere Scala. I denne Scala-vejledning bruger vi IntelliJ IDEA, som giver fremragende Scala-understøttelse lige fra starten.
Når du besøger downloadlinket, finder du to udgaver af IntelliJ IDE.
Til denne Scala-tutorial downloader vi Community Edition, som er gratis og indeholder alt hvad du behøver for at skrive Scala-programmer.
Trin 1) Vælg Fællesskabsudgave.
Klik på rullemenuen på Community Edition på siden.
Den præsenterer en mulighed for at downloade IntelliJ IDE sammen med JBR, som indeholder en JDK-implementering (Java Development Kit) såsom OpenJDK, som Scala skal bruge for at kompilere og køre kode.
Trin 2) Kør installationen.
Når du har downloadet IntelliJ, skal du dobbeltklikke på installationsprogrammet og følge guiden på skærmen.
Trin 3) Vælg en placering.
Vælg en placering for at installere IDE.
Hvis du ikke downloadede pakken med JDK'en, beder installationsprogrammet dig stadig om at tilføje JDK'en via et afkrydsningsfelt under opsætningen.
Trin 4) Klik på Næste.
Lad de andre standardindstillinger være, som de er, og klik på Næste.
Scala Hello World-programmet
Trin 5) Klik på opstartsikonet.
Når installationen er færdig, skal du køre IntelliJ IDE ved at klikke på dens opstartsikon i startmenuen som et almindeligt program.
Du skal stadig tilføje Scala-plugin'et til IntelliJ. Klik på rullemenuen i konfigurationsmenuen nederst til højre på skærmen, og vælg indstillingen Plugins.
Søg efter Scala på fanen Marketplace. Plugin'et vises som det første resultat under tagget Sprog.
Trin 6) Installer pluginet.
Klik på Installer for at begynde at downloade Scala-plugin'et.
Trin 7) Genstart IDE'en.
Når downloadingen er færdig, bliver du bedt om at genstarte IDE'en, så det installerede plugin kan begynde at virke.
Efter genstart vender du tilbage til den samme side som før, men nu er Scala-plugin'et installeret og klar.
Trin 8) Vælg Opret projekt, hvilket fører til en side, hvor du kan vælge sproget til projektet.
Trin 9) Vælg Scala ved at markere afkrydsningsfeltet Scala og klikke på Næste.
Trin 10) Vælg en placering til at gemme projektfilen, og giv projektet et navn.
Hvis mappen ikke findes, beder IntelliJ om tilladelse til at oprette mappen. Accepter, og klik på Udfør. Du bliver derefter ført til dit Scala-projekt, som i øjeblikket ikke indeholder nogen Scala-kode.
Det tager lidt tid at indlæse indekser, så bare rolig, hvis du ikke kan interagere med IDE'et, mens der vises en statuslinje nederst. IDE'et indlæser de filer, der kræves for at køre Scala og udføre autofuldførelse.
Trin 11) Klik på fanen Projekt til venstre for IDE'en, og udvid den for at se projektets indhold.
På dette tidspunkt er projektet tomt og indeholder kun en .idea-mappe og en hello-world.iml-fil genereret af IDE'en. Det interessante punkt er src-mappen, som indeholder kildekoden til projektet. Det er her, du opretter din første Scala-fil.
Trin 12) Højreklik på src for at åbne en menu og oprette en ny Scala-fil.
Vælg et navn til filen. Brug i denne Scala-vejledning Hej, og vælg derefter Objekt fra rullemenuen for indholdstypen for Scala-filen.
Når du har gjort dette, har du en Scala-fil, der indeholder et singleton-objekt, som du skal bruge til at køre koden.
Nu hvor du har en Scala-fil med et Hello-objekt, skal du skrive dit første program ved at udvide det objekt, du oprettede, ved hjælp af App-nøgleordet.
Udvidelse af objektet med App fortæller compileren, hvilken kode der skal køres, når programmet starter. Umiddelbart efter udvidelsen af App vises en grøn pil i venstre side, hvilket angiver, at programmet nu kan køres.
Inde i Hello-objektet skal du skrive funktionen println() for at udskrive teksten til konsollen. Kør programmet ved at klikke på den grønne pil.
Hvis du klikker på pilen, vises muligheden Kør Hello. Hvis du vælger den, kompileres koden, og efter et par sekunder vises programmets output i IntelliJ-konsollen.
Du har nu installeret Scala og kørt dit første program.
Hvad du kan gøre med Scala
Scala bruges i vid udstrækning på tværs af mange domæner på grund af dens fleksibilitet og JVM-interoperabilitet. Almindelige anvendelsesscenarier inkluderer:
- Frontend webudvikling med ScalaJS.
- Mobiludvikling til Android og iOS med Scala Native.
- Server-side biblioteker såsom HTTP4S, Akka-Http og Play Framework.
- Tingenes internet (IoT) applikationer.
- Spiludvikling.
- Naturlig sprogbehandling ved hjælp af ScalaNLP-bibliotekspakken.
- Øvelse af avancerede teknikker såsom funktionel programmering og objektorienteret programmering sammen.
- Meget samtidige kommunikationsapplikationer ved hjælp af aktører, et bibliotek til JVM inspireret af Erlang.
- Maskinlæring med biblioteker som Figaro til probabilistisk programmering og Apache Spark til databehandling i stor skala.
Anonyme funktioner
Scala-sproget understøtter anonyme funktioner, også kaldet funktionsbogstaverFordi Scala er et funktionelt sprog, opdeler udviklere ofte store problemer i mange små opgaver og opretter mange funktioner. For at gøre dette nemt tillader Scala funktioner at være instansieret uden navnDu kan tildele dem direkte til variabler eller til definitioner ved hjælp af def, som vist i følgende Scala-eksempel:
val multiplyByTwo = (n:Int) => n * 2 def multiplyByThree = (n:Int) => n * 3
Du kan derefter bruge dem som almindelige funktioner ved at overføre parametre:
multiplyByTwo(3) //6 multiplyByThree(4) //12
Disse metoder er nyttige, når du ønsker ren og præcis kode. Anonyme funktioner er nyttige, når du definerer metoder, der er små og ikke kræver meget kode i deres brødtekst. De er meget enkle og kræver ingen ceremoni for at blive oprettet.
Disse metoder er ikke begrænset til funktioner med argumenter og kan bruges til at instantiere metoder, der ikke tager argumenter.
val sayHello = () => { println("hello") }
De fleste af disse anonyme funktioner bruges i andre dele af koden, hvor du har brug for en hurtig funktion på plads. Af denne grund kaldes de også for inline funktionerBrugen af anonyme funktioner er et almindeligt mønster, der vises i hele samlingsbiblioteket for at udføre hurtige handlinger på en samling.
For eksempel bruger filtermetoden en inline-funktion til at oprette en anden samling med kun de elementer, der opfylder de kriterier, der er defineret i den anonyme funktion.
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)
Her kontrollerer de anonyme funktioner, om værdien fra listen er ulige eller lige, og returnerer det matchende element.
//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
I Scala er det også muligt at bruge jokertegn, hvor den anonyme funktionsparameter ikke er navngivet. For eksempel:
var timesTwo = (_:Int) * 2 timesTwo(5) //10
I dette scenarie navngiver du ikke parameteren. Understregningen bruges til at repræsentere den.
Doven evaluering
De fleste sprog evaluerer variabler og funktionsparametre sekventielt, den ene efter den anden. I Scala er nøgleordet lazy hjælper med at håndtere værdier, som du ikke ønsker at evaluere, før de refereres til.
En variabel markeret som lazy evalueres ikke, hvor den er defineret, hvilket almindeligvis kaldes eager evaluation. Den evalueres kun, når der refereres til den senere i koden.
Dette kan være nyttigt, når evaluering af en værdi ville være en dyr beregning. Hvis værdien ikke altid er nødvendig, sparer du dig selv for at køre en dyr beregning, der kan gøre softwaren langsommere ved at gøre variablen doven.
lazy val myExpensiveValue = expensiveComputation def runMethod() = { if(settings == true) { use(myExpensiveValue) } else { use(otherValue) } }
Dette er ikke det eneste anvendelsesscenarie for dovne variabler. De hjælper også med at håndtere cirkulære afhængigheder i kode.
Hvis indstillingsflaget er falsk, behøver du ikke at bruge myExpensiveValue, hvilket sparer dig for at lave en dyr beregning. Dette er med til at sikre, at brugerne får en problemfri oplevelse, fordi ressourcer ikke spildes på værdier, der aldrig læses.
Dovenskab hjælper også med funktionsargumenter, hvor argumenterne kun bruges, når der refereres til dem inde i funktionen. Dette koncept kaldes Call-by-name-parametre.
def sometimesUsedString(someValue:String, defaultValue: => String) = { if(someValue != null) { use(defaultValue) } else { use(someValue) } }
Mange sprog bruger call-by-value-tilgangen til at evaluere argumenter. En parameter, der sendes via call-by-name, evalueres kun, når det er nødvendigt i funktionens brødtekst. Når værdien er evalueret, gemmes den og kan genbruges senere uden reevaluering, et koncept kendt som memoization.
Skriv inferens
I Scala behøver du ikke at deklarere typer for hver variabel, du opretter, fordi Scala-compileren kan udlede typer fra højre side af et udtryk. Dette gør din kode mere præcis og frigør dig fra at skrive standardtekster, hvor den forventede type er indlysende.
var first:String = "Hello, " var second:String = "World" var third = first + second //the compiler infers that third is of type String
Funktion af højere orden
En funktion af højere orden er en funktion, der kan tage funktioner som argumenter og returnere en funktion som en returtype. I Scala betragtes funktioner som førsteklasses borgere. Brug af funktioner på denne måde giver dig mulighed for at være meget fleksibel i de typer programmer, du kan bygge. Du kan oprette funktioner dynamisk og dynamisk tilføre funktionalitet til andre funktioner.
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = { myMathFunction(n) }
I funktionen ovenfor indtaster du en Int og en funktion, der tager en Int og returnerer en IntDu kan indsætte en hvilken som helst funktion af den signatur. Med signatur mener vi en funktions input og output. En signatur af Int => Int betyder, at en funktion tager et heltal som input og returnerer et heltal som output.
En underskrift af () => Int betyder, at en funktion ikke tager noget som input og returnerer et heltal som output. Et eksempel på en sådan funktion er en, der genererer et tilfældigt heltal.
def generateRandomInt() = { return scala.util.Random.nextInt() }
Ovenstående funktion har en signatur () => Int.
En funktion kan også have en signatur () => UnitDet betyder, at funktionen ikke tager noget med sig og ikke returnerer en type. Funktionen kan i stedet ændre en tilstand eller udføre en forudbestemt handling.
Den slags metoder anbefales ikke, fordi de kan fungere som en sort boks, der påvirker et system på ukendte måder. De er også sværere at teste. At have eksplicitte input- og outputtyper gør det muligt at ræsonnere over, hvad din funktion gør.
En funktion af højere orden kan også returnere en funktion. For eksempel kan du oprette en metode, der returnerer en potensfunktion, en funktion der tager et tal og anvender en potens på det.
def powerByFunction(n:Int): Int=>Int = { return (x:Int) => scala.math.pow(x,n).toInt }
Funktionen ovenfor tager et heltal. Dens returtype er en anonym funktion, der tager et heltal. x og bruger det som argument for potensfunktionen.
Currying
I Scala kan du konvertere en funktion, der tager to argumenter, til én, der tager ét argument ad gangen. Når du indsætter ét argument, anvender du det delvist og ender med en funktion, der tager det resterende argument for at fuldføre kaldet. Currying lader dig bygge funktioner ved delvist at tilføje nogle argumenter.
Dette er nyttigt til dynamisk at oprette funktioner, før du har et komplet sæt argumenter.
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m }
Hvis du har brug for en funktion, der ganges med et bestemt tal, behøver du ikke at oprette en anden multiplikationsmetode. Du kan anvende ét argument på den kurrerede funktion og genbruge resultatet:
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m } var multiplyByFive = multiplyTwoNumbers(5) _ multiplyByFive(4) //returns 20
Mønstertilpasning
Scala har en kraftfuld indbygget mekanisme, der hjælper dig med at kontrollere, om en variabel opfylder bestemte kriterier, ligesom en switch-sætning i Java eller en kæde af if/else-udsagn. Sproget understøtter mønstermatchning, som du kan bruge til at kontrollere, om en variabel er af en bestemt type. Mønstermatchning i Scala er kraftfuld og kan ødelægge komponenter, der har en unapply metode til at hente de felter, du er interesseret i, direkte fra den variable, der matches.
Scala-mønstermatchning giver også en mere behagelig syntaks end en switch-sætning.
myItem match { case true => //do something case false => //do something else case _ => //if none of the above do this by default }
Du sammenligner variablen med et sæt af muligheder. Når variablen opfylder kriterierne, evalueres udtrykket i højre side af den tykke pil (=>) og returneres som resultatet af matchen.
Understregningen fanger tilfælde, der ikke matches i koden, og afspejler dermed standardtilfældets funktion i en switch-sætning.
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 }
I ovenstående kode kan du finde typen af myItem variabel og, baseret på den, forgrene sig til specifik kode.
Mønstermatchning kontrollerer, om variablen matcher hvert tilfælde i rækkefølge.
Understregningen fungerer som en pladsholder, der matcher enhver betingelse, som de andre case-sætninger ikke matcher. Du tager en variabel myItem og ring til match fremgangsmåde.
- Tjek om
myItemistrueog kør logikken på højre side af den tykke pil “=>”. - Brug understregningen til at matche alt, der ikke matcher nogen af de case-sætninger, der er defineret i koden.
Med case-klasser kan du destrukturere klassen til f.eks.tract-felter inde i objektet.
Ved anvendelse af sealed nøgleordet til at definere klasser, får du fordelen af at compileren grundigt kontrollerer de tilfælde, du forsøger at matche, og advarer dig, hvis du glemmer at håndtere et.
uforanderlighed
Det er muligt at oprette værdier, der ikke kan ændres af andre funktioner i Scala, ved at bruge val nøgleord. Dette opnås i Java ved at bruge final nøgleord. I Scala bruger du et val når man opretter en variabel i stedet for var, som er alternativet for muterbare variabler.
En variabel defineret ved hjælp af val nøgleord er skrivebeskyttet, hvorimod et, der er defineret med var kan læses og ændres senere af andre funktioner eller af brugeren i koden.
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
Forsøger at tildele en værdi til myNumber efter at have erklæret det som en val kaster en kompileringsfejl: “reassignment to val.”
Hvorfor bruge uforanderlighed?
Uforanderlighed hjælper med at forhindre kode og andre programmører i at ændre værdier uventet, hvilket ville føre til uforudsigelige resultater. Hvis forbrugere af en værdi har brug for at ændre den, kan de i stedet lave en kopi. På denne måde forhindres fejl forårsaget af flere aktører, der ændrer den samme variabel.
Klasser og objekter
Objekter er virkelige enheder, og en klasse er en skabelon, der definerer objekter. Klasser har både tilstand og adfærd. Tilstandene er enten værdier eller variabler. Adfærden er metoderne i Scala.
Det næste afsnit viser, hvordan man definerer en klasse, instantierer den og bruger den i Scala.
Her er en klasse kaldet Rektangel, der har to værdier og to funktioner. Du kan også bruge parametrene l og b direkte som felter i programmet. Du har et objekt, der har en main-metode og instansierer klassen med to værdier.
Eksempel:
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) } }
Alle felter og metoder er som standard offentlige i Scala. Det er vigtigt at bruge override fordi toString er allerede defineret for hvert objekt i Scala.
Arv
Scala har flere typer arv (enkelt, flerniveau, multiple, hierarkisk og hybrid), der har meget til fælles med traditionelle former, der findes i JavaDu kan arve både fra klasser og fra egenskaber. Du arver medlemmerne af én klasse til en anden klasse ved hjælp af nøgleordet extendsDette muliggør genbrug.
Det er muligt at arve fra én klasse eller flere klasser. Det er også muligt at arve fra underklasser, der selv har deres egne superklasser, hvilket skaber et arvshierarki i processen.
I Scala-eksemplet nedenfor er basisklassen Circle, og den afledte klasse er SphereEn cirkel har en værdi kaldet radius, som nedarves i Sphere-klassen. Metoden calcArea tilsidesættes ved hjælp af nøgleordet override.
Eksempel:
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 } }
Abstraction
I Scala kan du lave mavemusklertract-metoder og medlemsfelter ved hjælp af abstract-klasser og træk. Indvendige mavemusklertract-klasser og træk, kan du definere mavemusklertract-felter uden at implementere dem.
Eksempel:
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" } }
Disse felter implementeres af de klasser, der udvider egenskaben eller abs'ernetract-klasse. Du kan bruge træk til at skabe ulempertracts for, hvad en applikation skal gøre, og derefter implementere disse metoder senere.
trait DatabaseService { def addItemName(itemName:String) def removeItem(itemId:Int) def updateItem(itemId:Int, newItemName:String) }
På denne måde kan du planlægge, hvordan en applikation vil se ud, uden at implementere metoderne, helping du forestiller dig, hvordan forskellige metoder vil se ud. Det følger et mønster kendt som programmering til mavemusklertractioner snarere end den faktiske implementering.
En klasse indledte med abstract søgeordet kan indeholde både mavemusklertract og ikke-abtract-metoder. Multipel arv understøttes dog ikke i abstract-klasser, så du kun kan strække én mavemuskeltract-klassen.
Singleton objekter
En singleton er en klasse, der kun instantieres én gang i et program. Den stammer fra et populært og nyttigt programmeringsmønster kendt som "singleton-mønsteret". Det er nyttigt til at oprette instanser, der er beregnet til at være langlivede og almindeligt tilgængelige i hele programmet, hvor tilstanden er integreret i koordineringen af begivenheder i et system. Det er nemt at oprette en sådan klasse i Scala, fordi Scala giver en simpel måde at oprette singletons på ved hjælp af object nøgleord.
object UserProfile { var userName = "" var isLoggedIn:Boolean = false }
Du kan derefter referere til dette objekt i hele programmet med den garanti, at alle dele af programmet ser de samme data, fordi der kun er én forekomst af det.
def getLoggedInStatus():Boolean = { return UserProfile.isLoggedIn } def changeLoggedInStatus():Boolean = { UserProfile.isLoggedIn = !UserProfile.isLoggedIn return UserProfile.isLoggedIn }
Konceptet med statiske medlemmer findes ikke i Scala, hvilket er grunden til, at man bruger singleton-objekter, der fungerer som statiske medlemmer af en klasse.
Implicitte klasser
Implicitte klasser er en funktion tilføjet i version 2.10 og bruges primært til at tilføje ny funktionalitet til eksisterende lukkede klasser.
implicit Nøgleordet skal defineres i en klasse, et objekt eller en egenskab. Den primære konstruktør for en implicit klasse skal have præcis ét argument i sin første parameterliste. Den kan også indeholde en yderligere implicit parameterliste.
I Scala-eksemplet nedenfor er der tilføjet en ny funktionalitet til at erstatte vokaler i en streng med *.
object StringUtil { implicit class StringEnhancer(str: String) { def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*") } }
Du skal importere den implicitte klasse i den klasse, hvor du bruger den.
import StringUtil.StringEnhancer object ImplicitEx extends App { val msg = "This is Guru99!" println(msg.replaceVowelWithStar) }
Objektorienteret programmering (OOP) vs. funktionel programmering (FP)
I OOP konstrueres programmer af grupperping data og de funktioner, der opererer på disse data, i stærkt forbundne enheder. Objekter bærer deres data i felter, og metoderne opererer på dem. I denne programmeringsstil er de vigtigste abstraction er dataene, fordi de metoder, der oprettes, er beregnet til at operere på dataene.
Funktionel programmeringadskiller derimod data og de funktioner, der opererer på dem. Dette gør det muligt for udviklere at behandle funktioner som abstraction og drivkraft ved modellering af programmer.
Scala muliggør funktionel programmering ved at behandle funktioner som førsteklasses borgere, hvilket giver dem mulighed for at blive sendt som værdier til andre funktioner og returneret som værdier. Kombinationen af disse to paradigmer har gjort Scala til et godt valg til at bygge kompleks software i brancher som datavidenskab.
Vigtige rammer på Scala
Her er nogle vigtige frameworks for Scala:
- Leg er en open source webapplikationsramme, der bruger MVC arkitekturUdgivet i 2007 og nu licenseret under Apache, blev det et af de mest populære frameworks på GitHub i 2013. Virksomheder som LinkedIn, Walmart, Samsung og Eero bruger dette framework.
- Elevator er et andet gratis webframework skrevet i Scala, lanceret i 2007. Foursquare bruger Lift-frameworket. Det er et højtydende framework, der er hurtigt at bygge med.
- Som leverer et værktøjssæt til at bygge meget samtidige, distribuerede og robuste meddelelsesdrevne applikationer på JVM'en.
- Katte er et bibliotek, der tilbyder mavemusklertractioner til funktionel programmering.
- Spark er en samlet analysemotor til storskala databehandling, der er meget anvendt i big data- og maskinlæringsarbejdsgange.
Samtidig support
- Værdierne i Scala er som standard uforanderlige, hvilket gør den meget tilpasningsdygtig til samtidige miljøer.
- Scala har mange funktioner, der gør den ideel til samtidige applikationer.
- Futures and Promises gør det lettere at behandle data asynkront og understøtter dermed parallelitet.
- Akka er et værktøjssæt, der bruger aktør-samtidighedsmodellen. Aktører handler, når de modtager beskeder.
- Samtidig brug af tråde fra Java understøttes også i Scala.
- Streambehandling er en anden fantastisk funktion, der muliggør kontinuerlig databehandling i realtid.
Scala har nogle af de bedste samtidighedsbiblioteker i Java økosystem:
- Native Java tråde.
- Fibre fra biblioteker som Vertx.
- ZIO, et bibliotek med primitiver, der hjælper med at håndtere samtidighed og asynkron beregning.
- Software Transactional Memory (STM) til transaktioner.
- Future, som er indbygget i Scala-sproget.
Java vs. Scala
Her er de vigtigste forskelle mellem Java og Scala.
| Scala | Java |
|---|---|
| Mere kompakt og præcis. | Relativt større kodestykker. |
| Designet og udviklet til at være både objektorienteret og funktionel. Understøtter en bred vifte af funktionelle programmeringsfunktioner såsom samtidighed og uforanderlighed. | Oprindeligt udviklet som et objektorienteret sprog og begyndte at understøtte funktionelle programmeringsfunktioner i nyere versioner. Det er stadig ikke så stærkt som Scala til funktionel programmering. |
| Bruger aktørmodellen til at understøtte samtidighed. | Bruger den konventionelle trådbaserede model til samtidighed. |
| Understøtter frameworks som Play og Lift. | Understøtter Spring, Grails og mange flere. |
| Understøtter doven evaluering. | Understøtter ikke doven evaluering native. |
| Ingen statiske medlemmer. | Indeholder statiske medlemmer. |
| Understøtter operatøroverbelastning. | Understøtter ikke operatøroverbelastning. |
| Kompilering af kildekode er forholdsvis langsom. | Kompilering af kildekode er hurtigere end Scala. |
| Træk opfører sig som Java 8 grænseflader. | Java 8 grænseflader forsøger at bygge bro mellem klasser og grænseflader. |
| Omskrivning er nogle gange nødvendig ved opgradering af versioner. | Omskrivning er generelt ikke nødvendig mellem versioner. |
| Typesikkerhed giver stærk kodepålidelighed, men ingen absolut garanti for fejlfrihed. | Stærk statisk elektricitetping hjælper med at reducere mange runtime-fejl. |
| Har nogle begrænsninger for bagudkompatibilitet på tværs af større versioner. | Stærk langsigtet bagudkompatibilitet. |
| Operators behandles som metodekald. | Operators er speciel syntaks og er ikke metodekald. |
| Understøtter multipel arv ved hjælp af træk. | Understøtter ikke multipel arv ved hjælp af klasser; bruger i stedet grænseflader. |
| Code er skrevet i en kompakt form. | Code er skrevet i en mere ordrig form. |
| Scala indeholder ikke det statiske søgeord. | Java indeholder det statiske nøgleord. |






















