Scala-zelfstudie

โšก Slimme samenvatting

Deze Scala-handleiding introduceert een statisch getypeerde, op de JVM gebaseerde taal die objectgeoriรซnteerd en functioneel programmeren combineert. De handleiding behandelt installatie, syntaxis, kernfuncties en frameworks die Scala ideaal maken voor het bouwen van gelijktijdige, schaalbare en beknopte moderne applicaties.

  • ๐Ÿ”˜ Hybride paradigma: Scala combineert objectgeoriรซnteerd en functioneel programmeren op de JVM, waardoor ontwikkelaars onveranderlijkheid, eersteklas functies en traditionele klassenhiรซrarchieรซn kunnen combineren.
  • โ˜‘๏ธ Beknopte syntaxis: Type-inferentie, anonieme functies en patroonherkenning verminderen de hoeveelheid standaardcode in vergelijking met Java terwijl keeping De code is expressief en leesbaar.
  • โœ… Instellen met IntelliJ: Installeer de Community Edition IDE, voeg de Scala-plugin toe en maak een object aan dat de klasse App uitbreidt om het eerste "Hello World"-programma uit te voeren.
  • ๐Ÿงช Functionele bouwstenen: Luie evaluatie, currying, hogere-orde functies en onveranderlijkheid door middel van `val` ondersteunen schone en voorspelbare code.
  • ๏ธ Gelijktijdigheid en frameworks: Akka-acteurs, Futures, Play, Lift en Spark Scala is daardoor een sterke keuze voor gedistribueerde systemen, webapplicaties en data-engineering.

Scala-zelfstudie

Wat is Scala?

Scala Scala is een statisch getypeerde programmeertaal die objectgeoriรซnteerd en functioneel programmeren combineert om de schaalbaarheid van applicaties te verbeteren. Scala draait voornamelijk op het JVM-platform, maar ontwikkelaars kunnen het ook gebruiken om software te schrijven voor native platforms via Scala-Native, of voor de browser via Scala.js en de JavaScript looptijd.

Scala is een schaalbare taal die gebruikt wordt om software te bouwen voor meerdere platformen, en dat is precies hoe de taal aan zijn naam is gekomen. De taal is ontworpen om een โ€‹โ€‹aantal problemen met de omslachtigheid van code op te lossen die vaak voorkomen in Java terwijl het toch beknopt blijft. Scala is ontworpen door Martin Odersky en de eerste publieke release verscheen in 2004.

Waarom Scala leren

Dit zijn de belangrijkste redenen om de programmeertaal Scala te leren:

  • Scala is gemakkelijk te leren voor objectgeoriรซnteerde programmeurs en Java ontwikkelaars, en het is de afgelopen jaren uitgegroeid tot een van de populairste programmeertalen.
  • Scala biedt gebruikers eersteklas functies.
  • Scala kan worden uitgevoerd op de JVMwaardoor de weg wordt vrijgemaakt voor interoperabiliteit met andere talen.
  • Het is ontworpen voor gelijktijdige, gedistribueerde en robuuste, berichtgestuurde applicaties, waardoor het een van de meest gevraagde programmeertalen van dit decennium is.
  • Het is een beknopte, krachtige taal die snel kan meegroeien met de behoeften van de gebruikers.
  • Het is objectgeoriรซnteerd en bevat veel functionele programmeerfuncties, waardoor ontwikkelaars veel flexibiliteit hebben bij het schrijven van code.
  • Scala biedt Duck Ty aanping via structurele typen.
  • Het bevat minder standaardteksten dan Java.
  • De frameworks Lift en Play, die in Scala zijn geschreven, blijven zich ontwikkelen en winnen aan populariteit.

Hoe Scala te installeren

Om Scala-programma's te kunnen schrijven, moet je het op je computer installeren. Ga hiervoor naar de officiรซle website. https://www.scala-lang.org/download/ Om de nieuwste versie van Scala te downloaden.

Als je op de link klikt, krijg je twee opties om Scala te installeren. Voor deze Scala-handleiding gebruiken we de IntelliJ IDEA, wat uitstekende Scala-ondersteuning biedt.

Hoe Scala te installeren

Zodra je op de downloadlink klikt, vind je twee versies van de IntelliJ IDE.

Voor deze Scala-tutorial downloaden we de Community Edition, die gratis is en alles bevat wat je nodig hebt om Scala-programma's te schrijven.

Downloadpagina van IntelliJ Community Edition

Stap 1) Selecteer de Community-editie.
Klik op de pagina op het dropdownmenu bij 'Community Edition'.

Het biedt de mogelijkheid om de IntelliJ IDE samen met JBR te downloaden, dat een JDK-implementatie bevat (Java Een ontwikkelingskit (zoals OpenJDK) die Scala nodig heeft om code te compileren en uit te voeren.

Download IntelliJ met JBR

Stap 2) Voer de installatie uit.
Nadat je IntelliJ hebt gedownload, dubbelklik je op het installatieprogramma en volg je de instructies op het scherm.

IntelliJ installatiewizard

Stap 3) Kies een locatie.
Kies een locatie om de IDE te installeren.

Kies de installatiemap

Als je het pakket met de JDK niet hebt gedownload, vraagt โ€‹โ€‹het installatieprogramma je tijdens de installatie alsnog om de JDK toe te voegen via een selectievakje.

JDK-selectievakje tijdens installatie

Stap 4) Klik op Volgende.
Laat de overige standaardinstellingen ongewijzigd en klik op Volgende.

Standaardopties van de installatie

Scala Hello World-programma

Stap 5) Klik op het opstartpictogram.
Zodra de installatie is voltooid, start u de IntelliJ IDE door op het opstartpictogram in het Startmenu te klikken, net zoals u een gewone applicatie zou starten.

Welkomstscherm van IntelliJ

Je moet de Scala-plugin nog toevoegen aan IntelliJ. Klik op het dropdownmenu in het configuratiemenu rechtsonder in het scherm en selecteer de optie Plugins.

Menu configureren voor plug-ins

IntelliJ plugins marktplaats

Ga naar het tabblad Marketplace en zoek naar Scala. De plugin verschijnt als eerste resultaat onder de tag Talen.

Stap 6) Installeer de plug-in.
Klik op Installeren om de Scala-plugin te downloaden.

Installeer de Scala-plugin

Stap 7) Start de IDE opnieuw op.
Nadat de download is voltooid, wordt u gevraagd de IDE opnieuw op te starten, zodat de geรฏnstalleerde plug-in kan gaan werken.

IntelliJ opnieuw opstarten

Na het opnieuw opstarten kom je op dezelfde pagina terecht als voorheen, maar nu is de Scala-plugin geรฏnstalleerd en klaar voor gebruik.

Stap 8) Selecteer 'Project maken'. Je komt dan op een pagina waar je de taal voor het project kunt kiezen.

Een nieuw project aanmaken in IntelliJ

Stap 9) Kies Scala door het selectievakje Scala aan te vinken en klik op Volgende.

Selecteer de Scala-taal

Stap 10) Kies een locatie om het projectbestand op te slaan en geef het project een naam.

Naam en locatie van het project

Als de map niet bestaat, vraagt โ€‹โ€‹IntelliJ toestemming om de map aan te maken. Accepteer en klik op Voltooien. Je wordt vervolgens naar je Scala-project geleid, dat momenteel geen Scala-code bevat.

Het laden van de indexen duurt even, dus maak je geen zorgen als je niet met de IDE kunt werken terwijl er een voortgangsbalk onderin het scherm verschijnt. De IDE laadt de bestanden die nodig zijn om Scala uit te voeren en automatische aanvulling te bieden.

Stap 11) Klik op het tabblad 'Project' aan de linkerkant van de IDE en vouw het uit om de inhoud van het project te bekijken.

Projecttabblad uitbreiden

Op dit punt is het project leeg en bevat het alleen een .idea-map en een hello-world.iml-bestand dat door de IDE is gegenereerd. Het belangrijkste is de src-map, die de broncode van het project bevat. Hier maak je je eerste Scala-bestand aan.

Stap 12) Klik met de rechtermuisknop op src om een โ€‹โ€‹menu te openen en een nieuw Scala-bestand aan te maken.

Maak een nieuw Scala-bestand

Kies een naam voor het bestand. Voor deze Scala-handleiding gebruiken we de volgende naam: halloKies vervolgens 'Object' uit het dropdownmenu voor het inhoudstype van het Scala-bestand.

Kies objectsoort

Als je dit doet, heb je een Scala-bestand dat een singleton-object bevat waarmee je de code kunt uitvoeren.

Singleton-object gemaakt

Nu je een Scala-bestand hebt met een Hello-object, schrijf je je eerste programma door het object dat je hebt gemaakt uit te breiden met het trefwoord App.

Door het object uit te breiden met App, geef je de compiler aan welke code moet worden uitgevoerd wanneer het programma start. Direct na het uitbreiden van App verschijnt er een groene pijl aan de linkerkant, die aangeeft dat het programma nu uitvoerbaar is.

Voer de pijltoets uit in IntelliJ

Voer de optie 'Hallo' uit'

Schrijf binnen het Hello-object de functie println() om de tekst naar de console af te drukken. Start het programma door op de groene pijl te klikken.

Door op de pijl te klikken, verschijnt de optie 'Run Hello'. Als je deze selecteert, wordt de code gecompileerd en na een paar seconden verschijnt de programma-uitvoer in de IntelliJ-console.

"Hello World" wordt in de console weergegeven.

Je hebt Scala nu succesvol geรฏnstalleerd en je eerste programma uitgevoerd.

Wat je met Scala kunt doen

Scala wordt vanwege zijn flexibiliteit en compatibiliteit met de JVM veelvuldig gebruikt in diverse domeinen. Veelvoorkomende toepassingen zijn onder andere:

  • Frontend webontwikkeling met ScalaJS.
  • Mobiele ontwikkeling voor Android en iOS met Scala Native.
  • Server-side bibliotheken zoals HTTP4S, Akka-Http en het Play Framework.
  • Toepassingen van het Internet der Dingen (IoT).
  • Spelontwikkeling.
  • Natuurlijke taalverwerking met behulp van de ScalaNLP-bibliotheeksuite.
  • Het gelijktijdig oefenen van geavanceerde technieken zoals functioneel programmeren en objectgeoriรซnteerd programmeren.
  • Zeer gelijktijdige communicatietoepassingen met behulp van actors, een bibliotheek voor de JVM geรฏnspireerd op Erlang.
  • Machine learning met bibliotheken zoals Figaro voor probabilistisch programmeren en Apache. Spark voor grootschalige gegevensverwerking.

Anonieme functies

De programmeertaal Scala ondersteunt anonieme functies, ook wel anonieme functies genoemd. functie letterlijkeOmdat Scala een functionele taal is, splitsen ontwikkelaars grote problemen vaak op in veel kleine taken en maken ze veel functies. Om dit te vereenvoudigen, staat Scala toe dat functies geรฏnstantieerd zonder naamJe kunt ze rechtstreeks toewijzen aan variabelen of aan definities met behulp van def, zoals blijkt uit het volgende Scala-voorbeeld:

val multiplyByTwo = (n:Int) => n * 2
def multiplyByThree = (n:Int) => n * 3

Je kunt ze vervolgens gebruiken als gewone functies door parameters door te geven:

multiplyByTwo(3)
//6

multiplyByThree(4)
//12

Deze methoden komen goed van pas wanneer je schone en beknopte code wilt. Anonieme functies zijn handig bij het definiรซren van methoden die klein zijn en niet veel code in hun body vereisen. Ze zijn erg eenvoudig en vereisen geen verdere handelingen bij het aanmaken.

Deze methoden zijn niet beperkt tot functies met argumenten en kunnen worden gebruikt om methoden te instantiรซren die geen argumenten vereisen.

val sayHello = () => { println("hello") }

De meeste van deze anonieme functies worden gebruikt in andere delen van de code waar je snel een functie nodig hebt. Om die reden worden ze ook wel aangeduid als inline-functiesHet gebruik van anonieme functies is een veelvoorkomend patroon in de bibliotheek voor collecties om snelle acties op een collectie uit te voeren.

De filtermethode gebruikt bijvoorbeeld een inline-functie om een โ€‹โ€‹andere verzameling te creรซren met alleen de elementen die voldoen aan de criteria die zijn gedefinieerd in de anonieme functie.

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)

Hier controleren de anonieme functies of de waarde in de lijst oneven of even is en retourneren ze het overeenkomende item.

//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

In Scala is het ook mogelijk om wildcards te gebruiken wanneer de parameter van de anonieme functie geen naam heeft. Bijvoorbeeld:

var timesTwo = (_:Int) * 2

timesTwo(5)
//10

In dit scenario hoeft u de parameter geen naam te geven. De underscore wordt gebruikt om deze aan te duiden.

Luie evaluatie

De meeste programmeertalen evalueren variabelen en functieparameters sequentieel, de een na de ander. In Scala wordt het sleutelwoord gebruikt om variabelen en functieparameters te evalueren. lazy Het helpt bij het omgaan met waarden die je pas wilt evalueren wanneer ernaar wordt verwezen.

Een variabele die als 'lazy' is gemarkeerd, wordt niet geรซvalueerd op de plek waar deze is gedefinieerd, wat algemeen bekend staat als 'eager evaluation'. De variabele wordt pas geรซvalueerd wanneer er later in de code naar wordt verwezen.

Dit kan handig zijn wanneer het evalueren van een waarde een kostbare berekening zou zijn. Als de waarde niet altijd nodig is, bespaar je jezelf een kostbare berekening die de software kan vertragen door de variabele 'lui' te maken.

lazy val myExpensiveValue = expensiveComputation

def runMethod() = {
    if(settings == true) {
        use(myExpensiveValue)
    } else {
        use(otherValue)
    }
}

Dit is niet het enige gebruiksscenario voor luie variabelen. Ze helpen ook bij het oplossen van circulaire afhankelijkheden in code.

Als de instellingsvlag onwaar is, hoeft u myExpensiveValue niet te gebruiken, waardoor u een kostbare berekening vermijdt. Dit draagt โ€‹โ€‹bij aan een soepele gebruikerservaring, omdat er geen resources worden verspild aan waarden die nooit worden gelezen.

Luiheid is ook handig bij functieargumenten, waarbij de argumenten pas worden gebruikt wanneer ze binnen de functie worden aangeroepen. Dit concept wordt 'call-by-name parameters' genoemd.

def sometimesUsedString(someValue:String, defaultValue: => String) = {
 if(someValue != null) {
   use(defaultValue)
 } else {
   use(someValue)
   }
 }

Veel programmeertalen gebruiken de 'call-by-value'-methode voor het evalueren van argumenten. Een parameter die via 'call-by-name' wordt doorgegeven, wordt alleen geรซvalueerd wanneer dat nodig is binnen de functiebody. Zodra de waarde is geรซvalueerd, wordt deze opgeslagen en kan deze later opnieuw worden gebruikt zonder opnieuw te hoeven worden geรซvalueerd; dit concept staat bekend als memoization.

Typ gevolgtrekking

In Scala hoef je niet voor elke variabele die je aanmaakt een type te declareren, omdat de Scala-compiler typen kan afleiden uit de rechterkant van een expressie. Dit maakt je code beknopter en voorkomt dat je veel overbodige code hoeft te schrijven wanneer het verwachte type duidelijk is.

var first:String = "Hello, "
var second:String = "World"
var third = first + second
//the compiler infers that third is of type String

Hogere-orde functie

Een hogere-ordefunctie is een functie die functies als argumenten kan accepteren en een functie als retourtype kan teruggeven. In Scala worden functies beschouwd als eersteklas burgers. Door functies op deze manier te gebruiken, kun je zeer flexibel zijn in de soorten programma's die je kunt bouwen. Je kunt dynamisch functies creรซren en dynamisch functionaliteit aan andere functies doorgeven.

def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = {
    myMathFunction(n)
}

In de bovenstaande functie geef je een parameter door. Int en een functie die een Int en retourneert een IntJe kunt elke functie met die signatuur doorgeven. Met signatuur bedoelen we de invoer en uitvoer van een functie. Een signatuur van Int => Int Dit betekent dat een functie een integer als invoer accepteert en een integer als uitvoer retourneert.

Een handtekening van () => Int Dit betekent dat een functie geen invoer accepteert en een integer als uitvoer retourneert. Een voorbeeld van zo'n functie is een functie die een willekeurige integer genereert.

def generateRandomInt() = {
 return scala.util.Random.nextInt()
}

De bovenstaande functie heeft een signatuur () => Int.

Een functie kan ook een signatuur hebben. () => UnitDit betekent dat de functie geen invoer accepteert en geen type retourneert. De functie kan in plaats daarvan een bepaalde status wijzigen of een vooraf bepaalde actie uitvoeren.

Dit soort methoden wordt afgeraden omdat ze als een black box kunnen fungeren en een systeem op onbekende manieren beรฏnvloeden. Ze zijn bovendien moeilijker te testen. Door expliciete invoer- en uitvoertypen te gebruiken, kun je precies begrijpen wat je functie doet.

Een hogere-orde functie kan ook een functie retourneren. Je zou bijvoorbeeld een methode kunnen maken die een machtsfunctie retourneert, een functie die een getal als invoer neemt en er een macht op toepast.

def powerByFunction(n:Int): Int=>Int = {
  return (x:Int) => scala.math.pow(x,n).toInt
}

De bovenstaande functie neemt een integer als argument. Het retourtype is een anonieme functie die een integer als argument neemt. x en gebruikt het als argument voor de machtsfunctie.

Curry

In Scala kun je een functie die twee argumenten accepteert, omzetten naar een functie die รฉรฉn argument tegelijk accepteert. Wanneer je รฉรฉn argument doorgeeft, pas je dit gedeeltelijk toe, waardoor je een functie krijgt die het resterende argument gebruikt om de aanroep te voltooien. Currying stelt je in staat functies te bouwen door argumenten gedeeltelijk toe te voegen.

Dit is handig voor het dynamisch creรซren van functies voordat je een complete set argumenten hebt.

def multiplyTwoNumbers(n:Int)(m:Int): Int = {
  return n * m
}

Als je een functie nodig hebt die met een specifiek getal vermenigvuldigt, hoef je geen aparte vermenigvuldigingsmethode te maken. Je kunt รฉรฉn argument aan de gecurriede functie doorgeven en het resultaat hergebruiken:

def multiplyTwoNumbers(n:Int)(m:Int): Int = {
  return n * m
}

var multiplyByFive = multiplyTwoNumbers(5) _

multiplyByFive(4)

//returns 20

Patroonaanpassing

Scala heeft een krachtig ingebouwd mechanisme waarmee je kunt controleren of een variabele aan bepaalde criteria voldoet, vergelijkbaar met een switch-statement in Java of een reeks if/else-instructies. De taal ondersteunt patroonherkenning, waarmee je kunt controleren of een variabele van een bepaald type is. Patroonherkenning in Scala is krachtig en kan componenten ontleden die een unapply methode om de velden waarin je geรฏnteresseerd bent rechtstreeks uit de variabele te halen die wordt vergeleken.

Scala-patroonmatching biedt bovendien een prettigere syntaxis dan een switch-statement.

myItem match {
  case true => //do something
  case false => //do something else
  case  _ => //if none of the above do this by default
}

Je vergelijkt de variabele met een reeks opties. Wanneer de variabele aan de criteria voldoet, wordt de expressie aan de rechterkant van de dikke pijl (=>) geรซvalueerd en als resultaat van de overeenkomst weergegeven.

De underscore vangt gevallen op die niet overeenkomen met de code, en weerspiegelt daarmee het gedrag van de default case in een switch-statement.

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
}

In de bovenstaande code kun je het type detecteren. myItem variabele en, op basis daarvan, vertakking naar specifieke code.

Patroonherkenning controleert of de variabele in elke volgorde overeenkomt.

De underscore fungeert als een placeholder die overeenkomt met elke voorwaarde waaraan de andere case-instructies niet voldoen. Je neemt een variabele. myItem en bel de match methode.

  • Controleren of myItem is true en voer de logica uit aan de rechterkant van de dikke pijl โ€œ=>โ€.
  • Gebruik de underscore om alles aan te duiden dat niet overeenkomt met een van de case-statements die in de code zijn gedefinieerd.

Met case classes kun je de klasse destructuren om bijvoorbeeldtract-velden binnen het object.

Via de sealed Door het trefwoord te gebruiken om klassen te definiรซren, profiteert u ervan dat de compiler alle gevallen die u probeert te matchen grondig controleert en u waarschuwt als u er een vergeet af te handelen.

Onveranderlijkheid

Het is mogelijk om waarden te creรซren die niet door andere functies in Scala kunnen worden gewijzigd door gebruik te maken van de val trefwoord. Dit wordt bereikt in Java door gebruik te maken van de final trefwoord. In Scala gebruik je een val bij het aanmaken van een variabele in plaats van var, wat het alternatief is voor veranderlijke variabelen.

Een variabele gedefinieerd met behulp van de val Het trefwoord is alleen-lezen, terwijl een trefwoord dat is gedefinieerd met var Deze gegevens kunnen later door andere functies of door de gebruiker in de code worden gelezen en gewijzigd.

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

Poging om een โ€‹โ€‹waarde toe te kennen aan myNumber nadat het als zodanig was verklaard val Geeft een compileerfout: "hertoewijzing aan val."

Waarom onveranderlijkheid gebruiken?

Onveranderlijkheid helpt voorkomen dat code en andere programmeurs onverwacht waarden wijzigen, wat tot onvoorspelbare resultaten zou leiden. Als gebruikers van een waarde deze moeten wijzigen, kunnen ze in plaats daarvan een kopie maken. Op deze manier worden bugs voorkomen die ontstaan โ€‹โ€‹doordat meerdere gebruikers dezelfde variabele wijzigen.

Klassen en objecten

Objecten zijn entiteiten uit de echte wereld, en een klasse is een sjabloon dat objecten definieert. Klassen hebben zowel een toestand als gedrag. De toestand bestaat uit waarden of variabelen. Het gedrag wordt in Scala weergegeven door de methoden.

In het volgende gedeelte wordt uitgelegd hoe je een klasse definieert, instantieert en gebruikt in Scala.

Hier is een klasse genaamd Rectangle die twee waarden en twee functies heeft. Je kunt ook de parameters gebruiken. l en b rechtstreeks als velden in het programma. Je hebt een object met een main-methode dat de klasse instantieert met twee waarden.

Voorbeeld:

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)
  }
}

In Scala zijn alle velden en methoden standaard openbaar. Het is essentieel om ze te gebruiken. override omdat toString is al gedefinieerd voor elk object in Scala.

Erfenis

Scala kent meerdere soorten overerving (enkelvoudig, meervoudig, meervoudig, hiรซrarchisch en hybride) die veel gemeen hebben met traditionele vormen die je aantreft in JavaJe kunt zowel van klassen als van traits erven. Je erft de leden van de ene klasse over naar een andere klasse met behulp van het sleutelwoord. extendsDit maakt hergebruik mogelijk.

Het is mogelijk om van รฉรฉn of meerdere klassen te erven. Het is ook mogelijk om van subklassen te erven die zelf weer superklassen hebben, waardoor een overervingshiรซrarchie ontstaat.

In het onderstaande Scala-voorbeeld is de basisklasse Circleen de afgeleide klasse is SphereEen cirkel heeft een waarde genaamd straal, die wordt overgeรซrfd in de Sphere-klasse. De methode calcArea wordt overschreven met behulp van het trefwoord override.

Voorbeeld:

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
    }
  }

Abstractie

In Scala kun je abs makentract-methoden en lidvelden met behulp van abstract-klassen en -eigenschappen. Binnenin abstract klassen en eigenschappen, je kunt abs definiรซrentract-velden zonder ze te implementeren.

Voorbeeld:

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"
    }
}

Deze velden worden geรฏmplementeerd door de klassen die de trait of abs uitbreiden.tract-klasse. Je kunt eigenschappen gebruiken om con te creรซren.tracts voor wat een applicatie moet doen en implementeer die methoden vervolgens later.

trait DatabaseService {
    def addItemName(itemName:String)
    def removeItem(itemId:Int)
    def updateItem(itemId:Int, newItemName:String)
}

Op deze manier kunt u plannen hoe een applicatie eruit zal zien zonder de methoden te implementeren.ping Je visualiseert hoe verschillende methoden eruit zullen zien. Het volgt een patroon dat bekend staat als programmeren om te abstraheren.tracde conclusies in plaats van de daadwerkelijke implementatie.

Een les voorafgegaan door de abstract Een trefwoord kan zowel abs als abs bevatten.tract en niet-abstract-methoden. Meervoudige overerving wordt echter niet ondersteund in abs.tract-klassen, zodat je slechts รฉรฉn abs kunt uitbreidentract-klasse.

Singleton-objecten

Een singleton is een klasse die slechts รฉรฉn keer in een programma wordt geรฏnstantieerd. Het is afkomstig van een populair en nuttig programmeerpatroon dat bekend staat als het "singleton-patroon". Het is handig voor het creรซren van instanties die bedoeld zijn om lang te bestaan โ€‹โ€‹en veelvuldig te worden gebruikt in het programma, waarbij de status essentieel is voor het coรถrdineren van gebeurtenissen in een systeem. Het creรซren van zo'n klasse in Scala is eenvoudig, omdat Scala een simpele manier biedt om singletons te creรซren met behulp van de object trefwoord.

object UserProfile {
    var userName = ""
    var isLoggedIn:Boolean = false
}

Je kunt dit object vervolgens in het hele programma gebruiken met de garantie dat alle onderdelen van het programma dezelfde gegevens zien, omdat er maar รฉรฉn instantie van bestaat.

def getLoggedInStatus():Boolean = {
   return UserProfile.isLoggedIn
}

def changeLoggedInStatus():Boolean = {
    UserProfile.isLoggedIn = !UserProfile.isLoggedIn
    return UserProfile.isLoggedIn
}

Het concept van statische leden bestaat niet in Scala. Daarom gebruik je singleton-objecten die zich gedragen als statische leden van een klasse.

Impliciete klassen

Impliciete klassen zijn een functie die is toegevoegd in versie 2.10 en worden voornamelijk gebruikt om nieuwe functionaliteit toe te voegen aan bestaande, gesloten klassen.

De implicit Het sleutelwoord moet gedefinieerd zijn in een klasse, object of trait. De primaire constructor van een impliciete klasse moet precies รฉรฉn argument in de eerste parameterlijst hebben. Deze mag ook een extra impliciete parameterlijst bevatten.

In het onderstaande Scala-voorbeeld is nieuwe functionaliteit toegevoegd om klinkers in een String te vervangen door *.

object StringUtil {
  implicit class StringEnhancer(str: String) {

    def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*")
  }
}

Je moet de impliciete klasse importeren in de klasse waar je deze gebruikt.

import StringUtil.StringEnhancer

object ImplicitEx extends App {
  val msg = "This is Guru99!"
  println(msg.replaceVowelWithStar)
}

Objectgeoriรซnteerd programmeren (OOP) versus functioneel programmeren (FP)

In OOP worden programma's geconstrueerd door groepen.ping Gegevens en de functies die op die gegevens werken, worden in sterk met elkaar verbonden eenheden ondergebracht. Objecten dragen hun gegevens in velden en de methoden werken daarop. In deze programmeerstijl vormen de belangrijkste elementen van de code de kern van de data.tracDe methode is gebaseerd op de data, omdat de ontwikkelde methoden bedoeld zijn om op die data te werken.

Functioneel programmerenAan de andere kant scheidt het de data van de functies die erop werken. Dit stelt ontwikkelaars in staat om functies als de absolute waarden te behandelen.tracen drijvende kracht bij het modelleren van programma's.

Scala maakt functioneel programmeren mogelijk door functies als volwaardige burgers te behandelen, waardoor ze als waarden aan andere functies kunnen worden doorgegeven en ook als waarden kunnen worden geretourneerd. De combinatie van deze twee paradigma's heeft Scala tot een uitstekende keuze gemaakt voor het bouwen van complexe software in sectoren zoals datawetenschap.

Belangrijke raamwerken over Scala

Hieronder vind je enkele belangrijke frameworks voor Scala:

  • Play is een open-source webapplicatieframework dat gebruik maakt van MVC-architectuurHet framework werd uitgebracht in 2007 en is nu gelicentieerd onder Apache. Tegen 2013 was het uitgegroeid tot een van de populairste frameworks op GitHub. Bedrijven zoals LinkedIn, Walmart, Samsung en Eero gebruiken dit framework.
  • lift Lift is een ander gratis webframework, geschreven in Scala en gelanceerd in 2007. Foursquare maakt gebruik van het Lift-framework. Het is een krachtig framework waarmee snel gebouwd kan worden.
  • Akka Biedt een toolkit voor het bouwen van zeer gelijktijdige, gedistribueerde en robuuste berichtgestuurde applicaties op de JVM.
  • Katten is een bibliotheek die abs biedttracties voor functioneel programmeren.
  • Spark is een uniforme analyse-engine voor grootschalige gegevensverwerking, die veelvuldig wordt gebruikt in big data- en machine learning-workflows.

Ondersteuning voor gelijktijdigheid

  • De waarden in Scala zijn standaard onveranderbaar, waardoor het zeer geschikt is voor omgevingen met gelijktijdige uitvoering.
  • Scala heeft veel eigenschappen die het ideaal maken voor parallelle applicaties.
  • Met Futures en Promises kunt u gegevens eenvoudiger asynchroon verwerken en zo parallellisme ondersteunen.
  • Akka is een toolkit die gebruikmaakt van het Actor-concurrencymodel. Actors voeren acties uit wanneer ze berichten ontvangen.
  • Gelijktijdigheid met behulp van threads van Java wordt ook ondersteund in Scala.
  • Streamverwerking is een andere fantastische functie die continue, realtime verwerking van gegevens mogelijk maakt.

Scala heeft enkele van de beste concurrency-bibliotheken in de wereld Java ecosysteem:

  • Native Java threads.
  • Fibers uit bibliotheken zoals Vertx.
  • ZIO is een bibliotheek met basisfunctionaliteiten die helpen bij het omgaan met gelijktijdigheid en asynchrone berekeningen.
  • Software Transactional Memory (STM) voor transacties.
  • Future, dat is ingebouwd in de Scala-taal.

Java versus Scala

Hier zijn de belangrijkste verschillen tussen Java en Schaal.

Scala Java
Compactere en bondigere versie. Relatief grotere stukken code.
Ontworpen en ontwikkeld om zowel objectgeoriรซnteerd als functioneel te zijn. Ondersteunt een breed scala aan functionele programmeerfuncties, zoals gelijktijdigheid en onveranderlijkheid. Oorspronkelijk ontwikkeld als een objectgeoriรซnteerde taal, ondersteunt het sinds recentere versies ook functioneel programmeren. Het is echter nog steeds niet zo sterk als Scala voor functioneel programmeren.
Maakt gebruik van het actormodel ter ondersteuning van gelijktijdigheid. Maakt gebruik van het conventionele op threads gebaseerde model voor gelijktijdigheid.
Ondersteunt frameworks zoals Play en Lift. Ondersteunt Spring, Grails en nog veel meer.
Ondersteunt luie evaluatie. Biedt geen native ondersteuning voor lazy evaluation.
Geen statische leden. Bevat statische leden.
Ondersteunt overbelasting van de operator. Ondersteunt geen overbelasting van de operator.
Het compileren van de broncode is relatief traag. Het compileren van de broncode gaat sneller dan met Scala.
Eigenschappen gedragen zich als Java 8 interfaces. Java 8 interfaces proberen de kloof tussen klassen en interfaces te overbruggen.
Bij het upgraden van versies is herschrijven soms nodig. Het is over het algemeen niet nodig om tussen versies te herschrijven.
Typeveiligheid biedt een hoge mate van codebetrouwbaarheid, maar geen absolute garantie dat de code foutloos is. Sterke statische elektriciteitping Helpt bij het verminderen van veel runtimefouten.
Heeft enkele beperkingen qua achterwaartse compatibiliteit tussen belangrijke versies. Sterke achterwaartse compatibiliteit op de lange termijn.
OperaTors worden behandeld als methodeaanroepen. OperaTors zijn speciale syntax en geen methodeaanroepen.
Ondersteunt meervoudige overerving met behulp van eigenschappen. Ondersteunt geen meervoudige overerving via klassen; maakt in plaats daarvan gebruik van interfaces.
Code is in een compacte vorm geschreven. Code is in een meer uitgebreide vorm geschreven.
Scala bevat niet het statische zoekwoord. Java bevat het statische trefwoord.

Veelgestelde vragen

Scala heeft een steilere leercurve dan Java omdat het objectgeoriรซnteerde en functionele stijlen combineert. Ontwikkelaars met Java Door ervaring leer je de basisprincipes meestal snel. Oefenen met kleine projecten en de Scala REPL versnelt het leerproces.

Ja. Scala wordt nog steeds gebruikt om grootschalige systemen aan te drijven bij bedrijven die Akka gebruiken. Sparken Kafka. De vraag blijft groot in data-engineering, fintech en gedistribueerde systemen, waar JVM-prestaties en functioneel programmeren waardevol zijn.

Ja. Moderne AI-codeerassistenten begrijpen de Scala-syntaxis, het typesysteem en frameworks zoals Akka. SparkZe helpen bij het genereren van standaardcode, suggereren functionele patronen, leggen compilerfouten uit en herstructureren code, waardoor de ontwikkeling voor zowel beginners als experts wordt versneld.

Scala stuurt Apache aan. SparkScala is de toonaangevende engine voor grootschalige dataverwerking in AI-pipelines. Bibliotheken zoals Breeze, Smile en Figaro ondersteunen numerieke berekeningen, machine learning en probabilistische modellering, waardoor Scala een sterke keuze is voor data science in productieomgevingen.

Een `val` creรซert een onveranderlijke binding die direct wordt geรซvalueerd. Een `var` creรซert een veranderlijke binding die opnieuw kan worden toegewezen. Een `lazy val` stelt de evaluatie uit tot de waarde voor het eerst wordt opgevraagd en slaat het resultaat vervolgens op voor latere leesbewerkingen.

Vat dit bericht samen met: