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.

  • ๐Ÿ”˜ Hybridparadigme: Scala kombinerer objektorienteret og funktionel programmering pรฅ JVM'en, hvilket giver udviklere mulighed for at kombinere uforanderlighed, fรธrsteklasses funktioner og traditionelle klassehierarkier.
  • โ˜‘๏ธ Kortfattet syntaks: Typeinferens, anonyme funktioner og mรธnstermatchning reducerer standardteksten sammenlignet med Java mens keeping koden er udtryksfuld og lรฆsbar.
  • โœ… Opsรฆtning med IntelliJ: Installer Community Edition IDE'en, tilfรธj Scala-plugin'et, og opret et objekt, der udvider appen til at kรธre det fรธrste Hello World-program.
  • ๐Ÿงช Funktionelle byggesten: Doven evaluering, currying, funktioner af hรธjere orden og uforanderlighed gennem val, der understรธtter ren og forudsigelig kode.
  • ๐Ÿ› ๏ธ Samtidighed og rammer: Akka-skuespillere, Futures, Play, Lift og Spark gรธr Scala til et stรฆrkt valg til distribuerede systemer, webapplikationer og data engineering.

Scala tutorial

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.

Sรฅdan installeres Scala

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.

Downloadside for IntelliJ Community Edition

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.

Download IntelliJ med JBR

Trin 2) Kรธr installationen.
Nรฅr du har downloadet IntelliJ, skal du dobbeltklikke pรฅ installationsprogrammet og fรธlge guiden pรฅ skรฆrmen.

IntelliJ installationsguide

Trin 3) Vรฆlg en placering.
Vรฆlg en placering for at installere IDE.

Vรฆlg installationsmappe

Hvis du ikke downloadede pakken med JDK'en, beder installationsprogrammet dig stadig om at tilfรธje JDK'en via et afkrydsningsfelt under opsรฆtningen.

JDK-afkrydsningsfelt under installation

Trin 4) Klik pรฅ Nรฆste.
Lad de andre standardindstillinger vรฆre, som de er, og klik pรฅ Nรฆste.

Standardindstillinger for installationsprogram

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.

IntelliJ velkomstskรฆrm

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.

Konfigurationsmenu for plugins

IntelliJ plugins markedsplads

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.

Installer Scala-plugin

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.

Genstart IntelliJ-prompten

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.

Opret nyt projekt i IntelliJ

Trin 9) Vรฆlg Scala ved at markere afkrydsningsfeltet Scala og klikke pรฅ Nรฆste.

Vรฆlg Scala-sprog

Trin 10) Vรฆlg en placering til at gemme projektfilen, og giv projektet et navn.

Navngiv og find projektet

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.

Udvid projektfanen

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.

Opret 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.

Vรฆlg objekttype

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.

Singleton-objekt oprettet

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.

Kรธr pilen i IntelliJ

Kรธr Hello-indstillingen

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.

Hej Verden output i 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 myItem is true og 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.

Ofte Stillede Spรธrgsmรฅl

Scala har en stejlere lรฆringskurve end Java fordi den blander objektorienterede og funktionelle stilarter. Udviklere med Java Erfarne brugere tilegner sig normalt det grundlรฆggende hurtigt. ร˜v dig med smรฅ projekter, og Scala REPL fremskynder lรฆringen.

Ja. Scala fortsรฆtter med at drive store systemer i virksomheder, der bruger Akka, Sparkog Kafka. Efterspรธrgslen er fortsat stรฆrk inden for data engineering, fintech og distribuerede systemer, hvor JVM-ydeevne og funktionel programmering er vรฆrdifuld.

Ja. Moderne AI-kodningsassistenter forstรฅr Scala-syntaks, typesystem og frameworks som Akka og SparkDe hjรฆlper med at generere standardtekster, foreslรฅ funktionelle mรธnstre, forklare compilerfejl og refaktorere kode, hvilket fremskynder udviklingen for bรฅde begyndere og eksperter.

Scala driver Apache Spark, den fรธrende motor til storskala databehandling i AI-pipelines. Biblioteker som Breeze, Smile og Figaro understรธtter numerisk databehandling, maskinlรฆring og probabilistisk modellering, hvilket gรธr Scala til et stรฆrkt valg til produktionsdatalogi.

En vรฆrdi (val) opretter en uforanderlig binding, der evalueres med det samme. En variabel (variabel) opretter en foranderlig binding, der kan tildeles igen. En lazy val udsรฆtter evalueringen, indtil vรฆrdien tilgรฅs fรธrste gang, og cacher derefter resultatet til efterfรธlgende lรฆsninger.

Opsummer dette indlรฆg med: