Scala handledning
⚡ Smart sammanfattning
Scala Tutorial introducerar ett statiskt typat, JVM-baserat språk som förenar objektorienterad och funktionell programmering. Guiden täcker installation, syntax, kärnfunktioner och ramverk som gör Scala idealiskt för att bygga samtidiga, skalbara och koncisa moderna applikationer.

Vad är Scala?
Skala är ett statiskt typat programmeringsspråk som kombinerar objektorienterad och funktionell programmering för att förbättra skalbarheten hos applikationer. Scala körs huvudsakligen på JVM-plattformen, och utvecklare kan också använda det för att skriva programvara för native plattformar via Scala-Native, eller för webbläsaren via ScalaJs och JavaScript körning.
Scala är ett skalbart språk som används för att bygga programvara för flera plattformar, vilket är precis så det fick sitt namn. Språket utformades för att lösa flera av de utdragsproblem som finns i Java samtidigt som den förblev koncis. Martin Odersky designade Scala, och den första offentliga utgåvan kom ut 2004.
Varför lära sig Scala
Här är de främsta anledningarna till att lära sig programmeringsspråket Scala:
- Scala är lätt att lära sig för objektorienterade programmerare och Java utvecklare, och det har blivit ett av de populära språken de senaste åren.
- Scala erbjuder förstklassiga funktioner för användare.
- Scala kan köras på JVM, vilket banar väg för interoperabilitet med andra språk.
- Det är utformat för applikationer som är samtidiga, distribuerade och robusta meddelandedrivna, vilket gör det till ett av de mest efterfrågade språken under detta decennium.
- Det är ett koncist, kraftfullt språk som snabbt kan växa i takt med användarnas behov.
- Den är objektorienterad och innehåller många funktionella programmeringsfunktioner, vilket ger utvecklare stor flexibilitet i hur de skriver kod.
- Scala erbjuder Duck Typing genom strukturella typer.
- Den har mindre standard än Java.
- Ramverken Lift and Play, som är skrivna i Scala, fortsätter att mogna och växa i popularitet.
Hur man installerar Scala
För att börja skriva Scala-program måste du ha det installerat på din dator. För att göra detta, besök den officiella webbplatsen på https://www.scala-lang.org/download/ för att ladda ner den senaste versionen av Scala.
Efter länken visas två alternativ för att installera Scala. I den här Scala-handledningen kommer vi att använda IntelliJ IDEA, vilket ger utmärkt Scala-stöd direkt ur lådan.
När du besöker nedladdningslänken hittar du två utgåvor av IntelliJ IDE.
För den här Scala-handledningen kommer vi att ladda ner Community Edition, som är gratis och innehåller allt du behöver för att skriva Scala-program.
Steg 1) Välj Community-utgåva.
Klicka på rullgardinsmenyn Community Edition på sidan.
Den presenterar ett alternativ att ladda ner IntelliJ IDE tillsammans med JBR, som innehåller en JDK-implementering (Java Development Kit) som OpenJDK som Scala behöver för att kompilera och köra kod.
Steg 2) Kör installationen.
När du har laddat ner IntelliJ dubbelklickar du på installationsprogrammet och följer guiden på skärmen.
Steg 3) Välj en plats.
Välj en plats för att installera IDE.
Om du inte laddade ner paketet med JDK uppmanas du fortfarande att lägga till JDK via en kryssruta under installationen.
Steg 4) Klicka på Nästa.
Lämna de andra standardinställningarna som de är och klicka på Nästa.
Scala Hello World-programmet
Steg 5) Klicka på startikonen.
När installationen är klar kör du IntelliJ IDE genom att klicka på startikonen i Start-menyn som ett vanligt program.
Du behöver fortfarande lägga till Scala-pluginet i IntelliJ. Klicka på rullgardinsmenyn i konfigurationsmenyn längst ner till höger på skärmen och välj alternativet Plugins.
På fliken Marketplace söker du efter Scala. Plugin-programmet visas som det första resultatet under taggen Språk.
Steg 6) Installera plugin.
Klicka på Installera för att börja ladda ner Scala-pluginet.
Steg 7) Starta om IDE:n.
När nedladdningen är klar uppmanas du att starta om IDE:n så att det installerade plugin-programmet kan börja fungera.
Efter omstart återgår du till samma sida som tidigare, men nu är Scala-pluginet installerat och klart.
Steg 8) Välj Skapa projekt, vilket leder till en sida där du kan välja språk för projektet.
Steg 9) Välj Scala genom att markera kryssrutan Scala och klicka på Nästa.
Steg 10) Välj en plats att spara projektfilen och ge projektet ett namn.
Om katalogen inte finns, frågar IntelliJ om tillåtelse att skapa mappen. Godkänn och klicka på Slutför. Du kommer då till ditt Scala-projekt, som för närvarande inte innehåller någon Scala-kod.
Det tar lite tid att ladda index, så oroa dig inte om du inte kan interagera med IDE:n medan en förloppsindikator visas längst ner. IDE:n laddar de filer som krävs för att köra Scala och tillhandahålla autokomplettering.
Steg 11) Klicka på fliken Projekt till vänster om IDE:n och expandera den för att se projektets innehåll.
Vid det här laget är projektet tomt och innehåller endast en .idea-mapp och en hello-world.iml-fil som genereras av IDE:n. Det intressanta är src-mappen, som innehåller källkoden för projektet. Det är här du skapar din första Scala-fil.
Steg 12) Högerklicka på src för att öppna en meny och skapa en ny Scala-fil.
Välj ett namn för filen. För den här Scala-handledningen, använd hallåoch välj sedan Objekt från rullgardinsmenyn för innehållstypen för Scala-filen.
När du har gjort detta har du en Scala-fil som innehåller ett singleton-objekt som du kommer att använda för att köra koden.
Nu när du har en Scala-fil med ett Hello-objekt, skriv ditt första program genom att utöka objektet du skapade med hjälp av nyckelordet App.
Att utöka objektet med App anger vilken kod som ska köras när programmet startar. Omedelbart efter att App har utökats visas en grön pil på vänster sida, vilket indikerar att programmet nu är körbart.
Inuti Hello-objektet skriver du funktionen println() för att skriva ut texten till konsolen. Kör programmet genom att klicka på den gröna pilen.
Om du klickar på pilen visas alternativet Kör Hello. Om du väljer det kompileras koden, och efter några sekunder visas programmets utdata i IntelliJ-konsolen.
Du har nu installerat Scala och kört ditt första program.
Vad du kan göra med Scala
Scala används flitigt inom många områden på grund av dess flexibilitet och JVM-interoperabilitet. Vanliga användningsområden inkluderar:
- Frontend-webbutveckling med ScalaJS.
- Mobil utveckling för Android och iOS med Scala Native.
- Serversidesbibliotek som HTTP4S, Akka-Http och Play Framework.
- Sakernas internet (IoT)-applikationer.
- Spelutveckling.
- Naturlig språkbehandling med hjälp av ScalaNLP-bibliotekssviten.
- Att öva avancerade tekniker som funktionell programmering och objektorienterad programmering tillsammans.
- Mycket samtidiga kommunikationsapplikationer med aktörer, ett bibliotek för JVM inspirerat av Erlang.
- Maskininlärning med bibliotek som Figaro för probabilistisk programmering och Apache Spark för storskalig databehandling.
Anonyma funktioner
Scala-språket stöder anonyma funktioner, även kallade funktionsliteralEftersom Scala är ett funktionellt språk bryter utvecklare ofta upp stora problem i många små uppgifter och skapar många funktioner. För att göra detta enkelt tillåter Scala att funktioner instansierat utan namnDu kan tilldela dem direkt till variabler eller till definitioner med hjälp av def, som visas i följande Scala-exempel:
val multiplyByTwo = (n:Int) => n * 2 def multiplyByThree = (n:Int) => n * 3
Du kan sedan använda dem som vanliga funktioner genom att skicka parametrar:
multiplyByTwo(3) //6 multiplyByThree(4) //12
Dessa metoder är praktiska när du vill ha ren och koncis kod. Anonyma funktioner är användbara när du definierar metoder som är små och inte kräver mycket kod i sin text. De är mycket enkla och kräver ingen ceremoni för att skapas.
Dessa metoder är inte begränsade till funktioner med argument och kan användas för att instansiera metoder som inte tar några argument.
val sayHello = () => { println("hello") }
De flesta av dessa anonyma funktioner används i andra delar av koden där du behöver en snabbfunktion på plats. Av denna anledning kallas de även för inline-funktionerAtt använda anonyma funktioner är ett vanligt mönster som förekommer i hela samlingsbiblioteket för att utföra snabba åtgärder över en samling.
Till exempel använder filtermetoden en inline-funktion för att skapa en annan samling med endast de element som uppfyller kriterierna som definieras i den anonyma funktionen.
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)
Här kontrollerar de anonyma funktionerna om värdet från listan är udda eller jämnt och returnerar matchande 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 är det också möjligt att använda jokertecken där den anonyma funktionsparametern inte är namngiven. Till exempel:
var timesTwo = (_:Int) * 2 timesTwo(5) //10
I det här scenariot namnger du inte parametern. Understreck används för att representera den.
Lat utvärdering
De flesta språk utvärderar variabler och funktionsparametrar sekventiellt, en efter en. I Scala är nyckelordet lazy hjälper till att hantera värden som du inte vill utvärdera förrän de refereras.
En variabel markerad som lazy utvärderas inte där den definieras, vilket allmänt kallas eager evaluation. Den utvärderas bara när den refereras senare i koden.
Detta kan vara användbart när utvärderingen av ett värde skulle vara en dyr beräkning. Om värdet inte alltid behövs, slipper du en dyr beräkning som kan göra programvaran långsammare genom att göra variabeln lat.
lazy val myExpensiveValue = expensiveComputation def runMethod() = { if(settings == true) { use(myExpensiveValue) } else { use(otherValue) } }
Detta är inte det enda användningsfallet för lata variabler. De hjälper också till att hantera cirkulära beroenden i kod.
Om inställningsflaggan är falsk behöver du inte använda myExpensiveValue, vilket sparar dig från att göra en dyr beräkning. Detta bidrar till att säkerställa att användarna får en smidig upplevelse eftersom resurser inte slösas bort på värden som aldrig läses.
Lathet hjälper också med funktionsargument, där argumenten bara används när de refereras inuti funktionen. Detta koncept kallas Call-by-name-parametrar.
def sometimesUsedString(someValue:String, defaultValue: => String) = { if(someValue != null) { use(defaultValue) } else { use(someValue) } }
Många språk använder call-by-value-metoden för att utvärdera argument. En parameter som skickas via call-by-name utvärderas endast när det behövs inuti funktionens innehåll. När värdet har utvärderats lagras det och kan återanvändas senare utan omvärdering, ett koncept som kallas memoization.
Skriv inferens
I Scala behöver du inte deklarera typer för varje variabel du skapar eftersom Scala-kompilatorn kan härleda typer från höger sida av ett uttryck. Detta gör att din kod blir mer koncis och du slipper skriva standardtexter där den förväntade typen är uppenbar.
var first:String = "Hello, " var second:String = "World" var third = first + second //the compiler infers that third is of type String
Funktion av högre ordning
En funktion av högre ordning är en funktion som kan ta funktioner som argument och returnera en funktion som en returtyp. I Scala betraktas funktioner som förstklassiga medborgare. Genom att använda funktioner på det här sättet kan du vara mycket flexibel i vilka typer av program du kan bygga. Du kan skapa funktioner dynamiskt och dynamiskt mata funktionalitet till andra funktioner.
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = { myMathFunction(n) }
I funktionen ovan skickar du in en Int och en funktion som tar en Int och returnerar en IntDu kan skicka in vilken funktion som helst av den signaturen. Med signatur menar vi en funktions indata och utdata. En signatur av Int => Int betyder att en funktion tar ett heltal som indata och returnerar ett heltal som utdata.
En signatur av () => Int betyder att en funktion inte tar någonting som indata och returnerar ett heltal som utdata. Ett exempel på en sådan funktion är en som genererar ett slumpmässigt heltal.
def generateRandomInt() = { return scala.util.Random.nextInt() }
Funktionen ovan har en signatur () => Int.
En funktion kan också ha en signatur () => UnitDet betyder att funktionen inte tar in något och inte returnerar någon typ. Funktionen kan istället ändra tillstånd eller utföra en förutbestämd åtgärd.
Den här typen av metoder uppmuntras inte eftersom de kan fungera som en svart låda som påverkar ett system på okända sätt. De är också svårare att testa. Att ha explicita in- och utdatatyper gör att du kan resonera kring vad din funktion gör.
En funktion av högre ordning kan också returnera en funktion. Du kan till exempel skapa en metod som returnerar en potensfunktion, en funktion som tar ett tal och tillämpar en potens på det.
def powerByFunction(n:Int): Int=>Int = { return (x:Int) => scala.math.pow(x,n).toInt }
Funktionen ovan tar ett heltal. Dess returtyp är en anonym funktion som tar ett heltal. x och använder det som argument för potensfunktionen.
Curry
I Scala kan du konvertera en funktion som tar två argument till en som tar ett argument i taget. När du skickar in ett argument tillämpar du det delvis och får en funktion som tar det återstående argumentet för att slutföra anropet. Med Currying kan du bygga funktioner genom att delvis lägga till några argument.
Detta är användbart för att skapa funktioner dynamiskt innan du har en komplett uppsättning argument.
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m }
Om du behöver en funktion som multiplicerar med ett specifikt tal behöver du inte skapa en annan multiplikationsmetod. Du kan tillämpa ett argument på den kurerade funktionen och återanvända resultatet:
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m } var multiplyByFive = multiplyTwoNumbers(5) _ multiplyByFive(4) //returns 20
Mönstermatchning
Scala har en kraftfull inbyggd mekanism som hjälper dig att kontrollera om en variabel uppfyller vissa kriterier, ungefär som en switch-sats i Java eller en kedja av if/else-satser. Språket stöder mönstermatchning, vilket du kan använda för att kontrollera om en variabel är av en viss typ. Mönstermatchning i Scala är kraftfull och kan förstöra komponenter som har en unapply metod för att hämta de fält du är intresserad av direkt från variabeln som matchas.
Skalamönstermatchning ger också en mer behaglig syntax än en switch-sats.
myItem match { case true => //do something case false => //do something else case _ => //if none of the above do this by default }
Du jämför variabeln med en uppsättning alternativ. När variabeln uppfyller kriterierna utvärderas uttrycket till höger om den feta pilen (=>) och returneras som resultatet av matchningen.
Understrecket fångar upp fall som inte matchas i koden, vilket speglar beteendet hos standardfallet i en switch-sats.
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 koden ovan kan du identifiera typen av myItem variabel och, baserat på den, förgrena sig till specifik kod.
Mönstermatchning kontrollerar om variabeln matchar varje fall i ordning.
Understrecket fungerar som en platsmarkör som matchar alla villkor som de andra fallsatserna inte matchar. Du tar en variabel myItem och ring match metod.
- Kolla vädret
myItemistrueoch kör logiken på höger sida om den feta pilen “=>”. - Använd understrecket för att matcha allt som inte matchar någon av de case-satser som definieras i koden.
Med fallklasser kan du destrukturera klassen till exempeltract-fält inuti objektet.
Med hjälp av sealed nyckelordet för att definiera klasser får du fördelen att kompilatorn noggrant kontrollerar de fall du försöker matcha och varnar dig om du glömmer att hantera ett.
Oföränderlighet
Det är möjligt att skapa värden som inte kan ändras av andra funktioner i Scala genom att använda val nyckelord. Detta uppnås i Java genom att använda final nyckelord. I Scala använder du ett val när man skapar en variabel istället för var, vilket är alternativet för muterbara variabler.
En variabel definierad med hjälp av val nyckelordet är skrivskyddat, medan ett som definieras med var kan läsas och ändras senare av andra funktioner eller av användaren 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
Försöker tilldela ett värde till myNumber efter att ha deklarerat det som en val utlöser ett kompileringsfel: "omtilldelning till val."
Varför använda Immutability?
Oföränderlighet hjälper till att förhindra att kod och andra programmerare ändrar värden oväntat, vilket skulle leda till oförutsägbara resultat. Om konsumenter av ett värde behöver ändra det kan de istället göra en kopia. På så sätt förhindras buggar som orsakas av att flera aktörer ändrar samma variabel.
Klasser och objekt
Objekt är verkliga enheter, och en klass är en mall som definierar objekt. Klasser har både tillstånd och beteenden. Tillstånden är antingen värden eller variabler. Beteendena är metoderna i Scala.
Nästa avsnitt visar hur man definierar en klass, instansierar den och använder den i Scala.
Här är en klass som heter Rektangel som har två värden och två funktioner. Du kan också använda parametrarna l och b direkt som fält i programmet. Du har ett objekt som har en main-metod och instansierar klassen med två värden.
Exempel:
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) } }
Alla fält och metoder är publika som standard i Scala. Det är viktigt att använda override därför att toString är redan definierad för varje objekt i Scala.
Arv
Scala har flera typer av arv (enkel, flernivå, multipel, hierarkisk och hybrid) som har mycket gemensamt med traditionella former som finns i JavaDu kan ärva både från klasser och från egenskaper. Du ärver medlemmarna i en klass till en annan klass med hjälp av nyckelordet extendsDetta möjliggör återanvändning.
Det är möjligt att ärva från en klass eller flera klasser. Det är också möjligt att ärva från underklasser som själva har sina egna superklasser, vilket skapar en arvshierarki i processen.
I Scala-exemplet nedan är basklassen Circle, och den härledda klassen är SphereEn cirkel har ett värde som kallas radie, vilket ärvs i Sphere-klassen. Metoden calcArea åsidosätts med hjälp av nyckelordet override.
Exempel:
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 skapa magmusklertract-metoder och medlemsfält med hjälp av abstract-klasser och egenskaper. Inre magmusklertract-klasser och egenskaper, du kan definiera magmusklertract-fält utan att implementera dem.
Exempel:
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" } }
Dessa fält implementeras av de klasser som utökar egenskapen eller abstract-klassen. Du kan använda egenskaper för att skapa nackdelartracts för vad en applikation ska göra och sedan implementera dessa metoder senare.
trait DatabaseService { def addItemName(itemName:String) def removeItem(itemId:Int) def updateItem(itemId:Int, newItemName:String) }
På så sätt kan du planera hur en applikation ska se ut utan att implementera metoderna, helping du föreställer dig hur olika metoder kommer att se ut. Det följer ett mönster som kallas programmering till magmusklertractioner snarare än till det faktiska genomförandet.
En klass inleddes med abstract sökordet kan innehålla både magmusklertract och icke-abdoministract-metoder. Multipel arv stöds dock inte i abstract-klasser, så att du bara kan sträcka ut en magetract-klass.
Singleton objekt
En singleton är en klass som bara instansieras en gång i ett program. Den kommer från ett populärt och användbart programmeringsmönster som kallas "singletonmönstret". Det är användbart för att skapa instanser som är avsedda att vara långlivade och allmänt åtkomliga i hela programmet, där tillståndet är integrerat i att koordinera händelser i ett system. Att skapa en sådan klass i Scala är enkelt eftersom Scala tillhandahåller ett enkelt sätt att skapa singletons med hjälp av object nyckelord.
object UserProfile { var userName = "" var isLoggedIn:Boolean = false }
Du kan sedan referera till detta objekt genom hela programmet med garantin att alla delar av programmet ser samma data eftersom det bara finns en instans av det.
def getLoggedInStatus():Boolean = { return UserProfile.isLoggedIn } def changeLoggedInStatus():Boolean = { UserProfile.isLoggedIn = !UserProfile.isLoggedIn return UserProfile.isLoggedIn }
Konceptet med statiska medlemmar existerar inte i Scala, vilket är anledningen till att man använder singleton-objekt som fungerar som statiska medlemmar i en klass.
Implicita klasser
Implicita klasser är en funktion som lades till i version 2.10 och används främst för att lägga till ny funktionalitet till befintliga slutna klasser.
Ocuco-landskapet implicit Nyckelordet ska definieras i en klass, ett objekt eller en egenskap. Den primära konstruktorn för en implicit klass måste ha exakt ett argument i sin första parameterlista. Den kan också inkludera en ytterligare implicit parameterlista.
I Scala-exemplet nedan har en ny funktionalitet lagts till för att ersätta vokaler i en sträng med *.
object StringUtil { implicit class StringEnhancer(str: String) { def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*") } }
Du måste importera den implicita klassen till den klass där du använder den.
import StringUtil.StringEnhancer object ImplicitEx extends App { val msg = "This is Guru99!" println(msg.replaceVowelWithStar) }
Objektorienterad programmering (OOP) kontra funktionell programmering (FP)
I OOP konstrueras program av grupperping data och de funktioner som arbetar med dessa data till starkt sammankopplade enheter. Objekt bär sina data i fält och metoderna arbetar med dem. I denna programmeringsstil är det huvudsakliga abstraction är data, eftersom metoderna som skapas är avsedda att fungera på data.
Funktionell programmeringseparerar å andra sidan data och de funktioner som arbetar med dem. Detta gör det möjligt för utvecklare att behandla funktioner som abstraction och drivkraft vid modellering av program.
Scala möjliggör funktionell programmering genom att behandla funktioner som förstklassiga medborgare, vilket gör att de kan skickas som värden till andra funktioner och även returneras som värden. Kombinationen av dessa två paradigm har gjort Scala till ett utmärkt val för att bygga komplex programvara inom branscher som data science.
Viktiga ramverk på Scala
Här är några viktiga ramverk för Scala:
- Spela är ett ramverk för webbapplikationer med öppen källkod som använder MVC-arkitekturSläpptes 2007 och är nu licensierad under Apache, och blev ett av de mest populära ramverken på GitHub år 2013. Företag som LinkedIn, Walmart, Samsung och Eero använder detta ramverk.
- Hiss är ett annat gratis webbramverk skrivet i Scala, lanserat 2007. Foursquare använder Lift-ramverket. Det är ett högpresterande ramverk som är snabbt att bygga med.
- Som tillhandahåller en verktygslåda för att bygga mycket samtidiga, distribuerade och robusta meddelandedrivna applikationer på JVM.
- Katter - Leecork är ett bibliotek som tillhandahåller magmusklertractioner för funktionell programmering.
- Spark är en enhetlig analysmotor för storskalig databehandling, som används flitigt i arbetsflöden inom stordata och maskininlärning.
Samtidighetsstöd
- Värdena i Scala är som standard oföränderliga, vilket gör den mycket anpassningsbar till samtidiga miljöer.
- Scala har många funktioner som gör den idealisk för samtidiga applikationer.
- Futures and Promises gör det lättare att bearbeta data asynkront, vilket stödjer parallellism.
- Akka är en verktygslåda som använder aktörs-samtidighetsmodellen. Aktörer agerar när de tar emot meddelanden.
- Samtidighet med hjälp av trådar från Java stöds även i Scala.
- Strömbehandling är en annan bra funktion som möjliggör kontinuerlig databehandling i realtid.
Scala har några av de bästa samtidighetsbiblioteken i Java ekosystem:
- Native Java trådar.
- Fibrer från bibliotek som Vertx.
- ZIO, ett bibliotek som har primitiva funktioner för att hantera samtidighet och asynkron beräkning.
- Programvarutransaktionsminne (STM) för transaktioner.
- Future, som är inbyggt i Scala-språket.
Java mot Scala
Här är de viktigaste skillnaderna mellan Java och Scala.
| Skala | Java |
|---|---|
| Mer kompakt och koncis. | Jämförelsevis större kodbitar. |
| Designad och utvecklad för att vara både objektorienterad och funktionell. Stöder en mängd olika funktionella programmeringsfunktioner såsom samtidighet och oföränderlighet. | Ursprungligen utvecklat som ett objektorienterat språk och började stödja funktionella programmeringsfunktioner i senare versioner. Det är fortfarande inte lika starkt som Scala för funktionell programmering. |
| Använder aktörsmodellen för att stödja samtidighet. | Använder den konventionella trådbaserade modellen för samtidighet. |
| Stöder ramverk som Play och Lift. | Stöder Spring, Grails och många fler. |
| Stöder lat utvärdering. | Stöder inte lat utvärdering inbyggt. |
| Inga statiska medlemmar. | Innehåller statiska medlemmar. |
| Stöder överbelastning av operatörer. | Stöder inte operatörsöverbelastning. |
| Kompilering av källkod är jämförelsevis långsam. | Kompilering av källkod är snabbare än Scala. |
| Egenskaper beter sig som Java 8 gränssnitt. | Java 8 gränssnitt försöker överbrygga klyftan mellan klasser och gränssnitt. |
| Omskrivning behövs ibland vid uppgradering av versioner. | Omskrivning krävs i allmänhet inte mellan versioner. |
| Typsäkerhet ger stark kodens tillförlitlighet men ingen absolut garanti för buggfri kod. | Stark statisk förmågaping hjälper till att minska många körtidsfel. |
| Har vissa begränsningar för bakåtkompatibilitet mellan större versioner. | Stark långsiktig bakåtkompatibilitet. |
| Operators behandlas som metodanrop. | Operators är speciell syntax och är inte metodanrop. |
| Stöder multipel nedärvning med hjälp av egenskaper. | Stöder inte multipel arv med hjälp av klasser; använder gränssnitt istället. |
| Code är skriven i kompakt form. | Code är skriven i en mer utförlig form. |
| Scala innehåller inte det statiska nyckelordet. | Java innehåller det statiska nyckelordet. |






















