Esercitazione Scala

โšก Riepilogo intelligente

Scala Tutorial introduce un linguaggio a tipizzazione statica basato sulla JVM che unisce la programmazione orientata agli oggetti e quella funzionale. La guida tratta l'installazione, la sintassi, le funzionalitร  principali e i framework che rendono Scala ideale per la creazione di applicazioni moderne, concorrenti, scalabili e concise.

  • ๐Ÿ”˜ Paradigma ibrido: Scala fonde la programmazione orientata agli oggetti e quella funzionale sulla JVM, consentendo agli sviluppatori di combinare immutabilitร , funzioni di prima classe e gerarchie di classi tradizionali.
  • โ˜‘๏ธ Sintassi concisa: Inferenza di tipo, funzioni anonime e corrispondenza di pattern riducono il codice ripetitivo rispetto a Java mentre mantieniping il codice รจ espressivo e leggibile.
  • โœ… Configurazione con IntelliJ: Installa l'IDE Community Edition, aggiungi il plugin Scala e crea un oggetto che estende App per eseguire il primo programma Hello World.
  • ๐Ÿงช Elementi costitutivi funzionali: La valutazione pigra, il currying, le funzioni di ordine superiore e l'immutabilitร  tramite val contribuiscono a un codice pulito e prevedibile.
  • ๏ธ Concorrenza e framework: Attori Akka, Futuri, Gioca, Solleva e Spark Ciรฒ rende Scala una scelta valida per sistemi distribuiti, applicazioni web e ingegneria dei dati.

Esercitazione Scala

Cos'รจ Scala?

Scala รจ un linguaggio di programmazione a tipizzazione statica che combina la programmazione orientata agli oggetti e quella funzionale per migliorare la scalabilitร  delle applicazioni. Scala viene eseguito principalmente sulla piattaforma JVM e gli sviluppatori possono anche utilizzarlo per scrivere software per piattaforme native tramite Scala-Native o per il browser tramite ScalaJs e JavaCopione tempo di esecuzione.

Scala รจ un linguaggio scalabile utilizzato per costruire software per piรน piattaforme, ed รจ proprio da qui che deriva il suo nome. Il linguaggio รจ stato progettato per risolvere diversi problemi di verbositร  riscontrati in Java pur rimanendo conciso. Martin Odersky ha progettato Scala e la prima versione pubblica รจ stata rilasciata nel 2004.

Perchรฉ imparare Scala

Ecco i principali motivi per imparare il linguaggio di programmazione Scala:

  • Scala รจ facile da imparare per i programmatori orientati agli oggetti e Java sviluppatori, ed รจ diventato uno dei linguaggi piรน popolari negli ultimi anni.
  • Scala offre agli utenti funzionalitร  di prim'ordine.
  • Scala puรฒ essere eseguito su JVMaprendo la strada all'interoperabilitร  con altri linguaggi.
  • รˆ progettato per applicazioni concorrenti, distribuite e resilienti basate su messaggi, il che lo rende uno dei linguaggi piรน richiesti di questo decennio.
  • Si tratta di un linguaggio conciso e potente, in grado di evolversi rapidamente in base alle esigenze dei suoi utenti.
  • รˆ un linguaggio orientato agli oggetti e include numerose caratteristiche della programmazione funzionale, offrendo agli sviluppatori molta flessibilitร  nel modo in cui scrivono il codice.
  • Scala offre Duck Typing attraverso tipologie strutturali.
  • Ha meno codice ripetitivo di Java.
  • I framework Lift e Play, scritti in Scala, continuano a maturare e a guadagnare popolaritร .

Come installare Scala

Per iniziare a scrivere programmi Scala, รจ necessario installarlo sul computer. Per farlo, visita il sito ufficiale all'indirizzo https://www.scala-lang.org/download/ per scaricare l'ultima versione di Scala.

Seguendo il link, ti โ€‹โ€‹vengono presentate due opzioni per installare Scala. Per questo tutorial su Scala, useremo l'opzione IntelliJ IDEA, che offre un eccellente supporto per Scala fin da subito.

Come installare Scala

Una volta cliccato sul link per il download, troverete due edizioni dell'IDE IntelliJ.

Per questo tutorial su Scala, scaricheremo la Community Edition, che รจ gratuita e include tutto il necessario per scrivere programmi in Scala.

Pagina di download di IntelliJ Community Edition

Passo 1) Seleziona Community Edition.
Nella pagina, fai clic sul menu a tendina relativo alla Community Edition.

Offre la possibilitร  di scaricare l'IDE IntelliJ insieme a JBR, che contiene un'implementazione JDK (Java Kit di sviluppo) come OpenJDK, necessario a Scala per compilare ed eseguire il codice.

Scarica IntelliJ con JBR

Passo 2) Avviare l'installazione.
Una volta scaricato IntelliJ, fai doppio clic sul file di installazione e segui la procedura guidata visualizzata sullo schermo.

procedura guidata di installazione di IntelliJ

Passo 3) Seleziona una posizione.
Scegli una posizione in cui installare l'IDE.

Selezionare la cartella di installazione

Se non hai scaricato il pacchetto con il JDK, il programma di installazione ti chiederร  comunque di aggiungere il JDK tramite una casella di controllo durante la configurazione.

casella di controllo JDK durante l'installazione

Passo 4) Fare clic su Avanti.
Lascia invariate le altre impostazioni predefinite e fai clic su Avanti.

Opzioni predefinite del programma di installazione

Programma Scala Ciao Mondo

Passo 5) Fai clic sull'icona di avvio.
Una volta completata l'installazione, avvia l'IDE IntelliJ facendo clic sulla sua icona di avvio nel menu Start, come una normale applicazione.

Schermata di benvenuto di IntelliJ

Devi ancora aggiungere il plugin Scala a IntelliJ. Fai clic sul menu a tendina nella sezione "Configura" in basso a destra dello schermo e seleziona l'opzione "Plugin".

Configura il menu per i plugin

Marketplace dei plugin di IntelliJ

Nella scheda Marketplace, cerca Scala. Il plugin apparirร  come primo risultato sotto il tag Lingue.

Passo 6) Installa il plugin.
Fai clic su Installa per avviare il download del plugin Scala.

Installa il plugin Scala

Passo 7) Riavvia l'IDE.
Al termine del download, verrร  richiesto di riavviare l'IDE affinchรฉ il plugin installato possa iniziare a funzionare.

Riavvia il prompt di IntelliJ

Dopo il riavvio, si torna alla stessa pagina di prima, ma ora il plugin Scala รจ installato e pronto all'uso.

Passo 8) Seleziona Crea progetto, che ti porterร  a una pagina in cui potrai scegliere la lingua per il progetto.

Crea un nuovo progetto in IntelliJ

Passo 9) Seleziona Scala spuntando la casella di controllo Scala e fai clic su Avanti.

Seleziona la lingua Scala

Passo 10) Seleziona una posizione in cui salvare il file di progetto e assegna un nome al progetto.

Denominare e localizzare il progetto

Se la directory non esiste, IntelliJ chiede l'autorizzazione per crearla. Accetta e fai clic su Fine. Verrai quindi reindirizzato al tuo progetto Scala, che al momento non contiene alcun codice Scala.

Il caricamento degli indici richiede del tempo, quindi non preoccuparti se non riesci a interagire con l'IDE mentre viene visualizzata una barra di avanzamento in basso. L'IDE sta caricando i file necessari per eseguire Scala e fornire il completamento automatico.

Passo 11) Fai clic sulla scheda Progetto a sinistra dell'IDE ed espandila per visualizzare il contenuto del progetto.

Espandi la scheda del progetto

A questo punto, il progetto รจ vuoto e contiene solo una cartella .idea e un file hello-world.iml generato dall'IDE. Il punto di interesse รจ la cartella src, che contiene il codice sorgente del progetto. รˆ qui che creerete il vostro primo file Scala.

Passo 12) Fai clic con il pulsante destro del mouse su src per aprire un menu e creare un nuovo file Scala.

Crea un nuovo file Scala

Scegli un nome per il file. Per questo tutorial su Scala, usa Ciao, quindi scegli Oggetto dal menu a tendina per il tipo di contenuto del file Scala.

Scegli il tipo di oggetto

Una volta fatto ciรฒ, avrai un file Scala che contiene un oggetto singleton che utilizzerai per eseguire il codice.

Oggetto Singleton creato

Ora che hai un file Scala con un oggetto Hello, scrivi il tuo primo programma estendendo l'oggetto che hai creato utilizzando la parola chiave App.

Estendendo l'oggetto con App, si indica al compilatore quale codice eseguire all'avvio del programma. Subito dopo l'estensione di App, sul lato sinistro compare una freccia verde che indica che il programma รจ ora eseguibile.

Eseguire la freccia in IntelliJ

Esegui l'opzione Hello

All'interno dell'oggetto Hello, scrivi la funzione println() per stampare il testo sulla console. Esegui il programma cliccando sulla freccia verde.

Facendo clic sulla freccia viene visualizzata l'opzione Esegui Hello. Selezionandola, il codice viene compilato e, dopo alcuni secondi, l'output del programma appare nella console di IntelliJ.

Output di Hello World nella console

Hai installato Scala con successo e puoi eseguire il tuo primo programma.

Cosa puoi fare con Scala

Scala รจ ampiamente utilizzato in molti ambiti grazie alla sua flessibilitร  e all'interoperabilitร  con la JVM. Esempi di utilizzo comuni includono:

  • Sviluppo web frontend con ScalaJS.
  • Sviluppo mobile per Android e iOS con Scala Native.
  • Librerie lato server come HTTP4S, Akka-Http e Play Framework.
  • Applicazioni dell'Internet delle cose (IoT).
  • Sviluppo del gioco.
  • Elaborazione del linguaggio naturale utilizzando la suite di librerie ScalaNLP.
  • Esercitarsi contemporaneamente in tecniche avanzate come la programmazione funzionale e la programmazione orientata agli oggetti.
  • Applicazioni di comunicazione altamente concorrenti che utilizzano attori, una libreria per la JVM ispirata a Erlang.
  • Apprendimento automatico con librerie come Figaro per la programmazione probabilistica e Apache Spark per l'elaborazione di dati su larga scala.

Funzioni anonime

Il linguaggio Scala supporta le funzioni anonime, chiamate anche letterali di funzionePoichรฉ Scala รจ un linguaggio funzionale, gli sviluppatori spesso scompongono i problemi di grandi dimensioni in molti piccoli compiti e creano molte funzioni. Per semplificare questo processo, Scala consente di definire le funzioni. istanziato senza nomeรˆ possibile assegnarli direttamente alle variabili o alle definizioni utilizzando def, come mostrato nel seguente esempio in Scala:

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

รˆ quindi possibile utilizzarle come normali funzioni passando dei parametri:

multiplyByTwo(3)
//6

multiplyByThree(4)
//12

Questi metodi risultano utili quando si desidera un codice pulito e conciso. Le funzioni anonime sono utili per definire metodi di piccole dimensioni che non richiedono molto codice al loro interno. Sono molto semplici e non necessitano di particolari accorgimenti per essere create.

Questi metodi non si limitano alle funzioni con argomenti e possono essere utilizzati per creare istanze di metodi che non accettano argomenti.

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

La maggior parte di queste funzioni anonime vengono utilizzate in altre parti del codice dove รจ necessaria una funzione rapida. Per questo motivo, vengono anche chiamate funzioni incorporateL'utilizzo di funzioni anonime รจ uno schema comune che ricorre nella libreria delle collezioni per eseguire azioni rapide su una collezione.

Ad esempio, il metodo filter accetta una funzione inline per creare un'altra collezione contenente solo gli elementi che soddisfano i criteri definiti nella funzione anonima.

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)

Qui le funzioni anonime verificano se il valore presente nell'elenco รจ pari o dispari e restituiscono l'elemento corrispondente.

//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 รจ anche possibile utilizzare i caratteri jolly quando il parametro della funzione anonima non ha un nome. Ad esempio:

var timesTwo = (_:Int) * 2

timesTwo(5)
//10

In questo scenario, non si specifica il nome del parametro. Il carattere di sottolineatura viene utilizzato per rappresentarlo.

Valutazione pigra

La maggior parte dei linguaggi valuta sequenzialmente variabili e parametri di funzione, uno dopo l'altro. In Scala, la parola chiave lazy Aiuta a gestire i valori che non si desidera valutare finchรฉ non vengono utilizzati come riferimento.

Una variabile contrassegnata come "lazy" non viene valutata nel punto in cui รจ definita, un meccanismo comunemente noto come "eager evaluation" (valutazione immediata). Viene valutata solo quando viene richiamata successivamente nel codice.

Questo puรฒ essere utile quando la valutazione di un valore richiederebbe un calcolo oneroso. Se il valore non รจ sempre necessario, si evita di eseguire un calcolo dispendioso che potrebbe rallentare il software, rendendo la variabile "pigra" (lazy).

lazy val myExpensiveValue = expensiveComputation

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

Questo non รจ l'unico caso d'uso per le variabili lazy. Aiutano anche a gestire le dipendenze circolari nel codice.

Se il flag delle impostazioni รจ impostato su false, non รจ necessario utilizzare myExpensiveValue, evitando cosรฌ un calcolo oneroso. Questo contribuisce a garantire un'esperienza utente fluida, poichรฉ le risorse non vengono sprecate per valori che non vengono mai letti.

La valutazione pigra รจ utile anche per gli argomenti delle funzioni, che vengono utilizzati solo quando vengono richiamati all'interno della funzione stessa. Questo concetto รจ chiamato parametri "passati per nome".

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

Molti linguaggi di programmazione utilizzano l'approccio "passa per valore" per la valutazione degli argomenti. Un parametro passato tramite "passa per nome" viene valutato solo quando necessario all'interno del corpo della funzione. Una volta valutato, il valore viene memorizzato e puรฒ essere riutilizzato in seguito senza doverlo rivalutare, un concetto noto come memoizzazione.

Digitare Inferenza

In Scala, non รจ necessario dichiarare il tipo per ogni variabile creata, perchรฉ il compilatore Scala puรฒ dedurlo dal lato destro di un'espressione. Questo permette di scrivere codice piรน conciso ed evita di dover scrivere codice ripetitivo quando il tipo previsto รจ ovvio.

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

Funzione di ordine superiore

Una funzione di ordine superiore รจ una funzione che puรฒ accettare altre funzioni come argomenti e restituire una funzione come tipo di ritorno. In Scala, le funzioni sono considerate elementi di prima classe. L'utilizzo delle funzioni in questo modo consente una grande flessibilitร  nella tipologia di programmi che รจ possibile realizzare. รˆ possibile creare funzioni dinamicamente e passare funzionalitร  dinamicamente ad altre funzioni.

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

Nella funzione sopra, si passa un Int e una funzione che prende un Int e restituisce un Int. Puoi passare qualsiasi funzione con quella firma. Per firma, intendiamo l'input e l'output di una funzione. Una firma di Int => Int significa che una funzione prende un Int come input e restituisce un Int come output.

Una firma di () => Int significa che una funzione non accetta alcun input e restituisce un Int come output. Un esempio di tale funzione รจ quella che genera un numero intero casuale.

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

La funzione sopra riportata ha una firma () => Int.

Anche una funzione puรฒ avere una firma () => UnitCiรฒ significa che la funzione non accetta alcun parametro in ingresso e non restituisce alcun tipo. La funzione puรฒ invece modificare uno stato o eseguire un'azione predeterminata.

Questi tipi di metodi non sono consigliati perchรฉ possono agire come una scatola nera che influenza un sistema in modi sconosciuti. Sono anche piรน difficili da testare. Avere tipi di input e output espliciti consente di ragionare su cosa fa la funzione.

Una funzione di ordine superiore puรฒ anche restituire una funzione. Ad esempio, si potrebbe creare un metodo che restituisce una funzione di elevamento a potenza, ovvero una funzione che prende un numero e gli applica una potenza.

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

La funzione sopra accetta un Int. Il suo tipo di ritorno รจ una funzione anonima che accetta un Int x e lo utilizza come argomento per la funzione potenza.

curry

In Scala, รจ possibile convertire una funzione che accetta due argomenti in una che ne accetta uno alla volta. Quando si passa un argomento, questo viene applicato parzialmente, ottenendo una funzione che accetta l'argomento rimanente per completare la chiamata. Il currying permette di costruire funzioni aggiungendo parzialmente alcuni argomenti.

Questo รจ utile per creare funzioni in modo dinamico prima di avere un set completo di argomenti.

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

Se hai bisogno di una funzione che moltiplichi per un numero specifico, non รจ necessario creare un altro metodo di moltiplicazione. Puoi applicare un argomento alla funzione con currying e riutilizzare il risultato:

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

var multiplyByFive = multiplyTwoNumbers(5) _

multiplyByFive(4)

//returns 20

Pattern Matching

Scala ha un potente meccanismo integrato che ti aiuta a verificare se una variabile corrisponde a determinati criteri, molto simile a un'istruzione switch in Java o una catena di istruzioni if/else. Il linguaggio supporta il pattern matching, che puoi usare per verificare se una variabile รจ di un tipo particolare. Il pattern matching in Scala รจ potente e puรฒ destrutturare i componenti che hanno un unapply metodo per ottenere i campi di interesse direttamente dalla variabile corrispondente.

Il pattern matching in Scala offre inoltre una sintassi piรน gradevole rispetto a un'istruzione switch.

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

Si confronta la variabile con un insieme di opzioni. Quando la variabile soddisfa i criteri, l'espressione a destra della freccia spessa (=>) viene valutata e restituisce il risultato della corrispondenza.

Il carattere di sottolineatura gestisce i casi che non trovano corrispondenza nel codice, replicando il comportamento del caso predefinito in un'istruzione switch.

class Animal(var legs:Int, var sound:String)
class Furniture(var legs:Int, var color:Int, var woodType:String)

myItem match {
case myItem:Animal => //do something
case myItem:Furniture => //do something else
case _ => //unknown type, do something else
}

Nel codice sopra, รจ possibile rilevare il tipo di myItem variabile e, in base a quella, diramare verso codice specifico.

Il pattern matching verifica se la variabile corrisponde a ciascun caso nell'ordine specificato.

Il trattino basso funziona come segnaposto che corrisponde a qualsiasi condizione che le altre istruzioni case non soddisfano. Prendi una variabile myItem e chiama il match metodo.

  • Controlla se myItem is true e la logica viene eseguita sul lato destro della freccia spessa โ€œ=>โ€.
  • Utilizzare il carattere di sottolineatura per indicare la corrispondenza con qualsiasi elemento che non corrisponda a nessuna delle istruzioni case definite nel codice.

Con le case class, puoi destrutturare la classe per es.traccampi t all'interno dell'oggetto.

Utilizzando il sealed Utilizzando la parola chiave `class` per definire le classi, si ottiene il vantaggio che il compilatore controlla in modo esaustivo i casi che si tenta di abbinare e avvisa se ci si dimentica di gestirne uno.

Immutabilitร 

รˆ possibile creare valori che non possono essere modificati da altre funzioni in Scala utilizzando val parola chiave. Ciรฒ si ottiene in Java tramite la configurazione di ricerca final parola chiave. In Scala, si usa una val quando si crea una variabile invece di var, che รจ l'alternativa per le variabili mutabili.

Una variabile definita utilizzando il val la parola chiave รจ di sola lettura, mentre quella definita con var puรฒ essere letto e modificato in seguito da altre funzioni o dall'utente nel codice.

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

Tentativo di assegnare un valore a myNumber dopo averlo dichiarato come un val genera un errore in fase di compilazione: "riassegnazione a val".

Perchรฉ usare l'Immutabilitร ?

L'immutabilitร  aiuta a impedire che il codice e altri programmatori modifichino i valori in modo inaspettato, il che porterebbe a risultati imprevedibili. Se chi utilizza un valore ha bisogno di modificarlo, puรฒ invece crearne una copia. In questo modo, si prevengono i bug causati da piรน soggetti che modificano la stessa variabile.

Classi e oggetti

Gli oggetti sono entitร  del mondo reale e una classe รจ un modello che definisce gli oggetti. Le classi hanno sia uno stato che dei comportamenti. Gli stati sono valori o variabili. I comportamenti sono i metodi in Scala.

La sezione successiva mostra come definire una classe, crearne un'istanza e utilizzarla in Scala.

Ecco una classe chiamata Rectangle che ha due valori e due funzioni. Puoi anche usare i parametri l and b direttamente come campi nel programma. Hai un oggetto che ha un metodo main e istanzia la classe con due valori.

Esempio:

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 tutti i campi e i metodi sono pubblici per impostazione predefinita. รˆ essenziale utilizzare override perchรฉ toString รจ giร  definito per ogni oggetto in Scala.

Ereditร 

Scala ha diversi tipi di ereditarietร  (singola, multilivello, multipla, gerarchica e ibrida) che condividono molto in comune con le forme tradizionali trovate in Javaรˆ possibile ereditare sia dalle classi che dai tratti. I membri di una classe vengono ereditati in un'altra classe utilizzando la parola chiave extendsCiรฒ consente il riutilizzo.

รˆ possibile ereditare da una o piรน classi. รˆ anche possibile ereditare da sottoclassi che a loro volta hanno le proprie superclassi, creando cosรฌ una gerarchia di ereditarietร .

Nell'esempio Scala riportato di seguito, la classe base รจ Circlee la classe derivata รจ SphereUn cerchio ha un valore chiamato raggio, che viene ereditato nella classe Sfera. Il metodo calcArea viene sovrascritto utilizzando la parola chiave override.

Esempio:

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

Abstracproduzione

In Scala, puoi creare assolutitracmetodi t e campi membro utilizzando abstracclassi e tratti t. Dentro gli addominalitracclassi e tratti, puoi definire gli assolutitraccampi t senza implementarli.

Esempio:

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

Questi campi sono implementati dalle classi che estendono il tratto o l'abstracclasse t. Puoi usare i tratti per creare contracdefinire cosa dovrebbe fare un'applicazione e poi implementare quei metodi in seguito.

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

In questo modo, puoi pianificare l'aspetto di un'applicazione senza implementare i metodi, aiutaping si immagina come appariranno i vari metodi. Segue uno schema noto come programmazione per l'astrazione.tracpiuttosto che all'effettiva implementazione.

Una lezione preceduta da abstract la parola chiave puรฒ contenere entrambi gli assolutitract e non-abstracmetodi t. Tuttavia, l'ereditarietร  multipla non รจ supportata in abstracclassi t, quindi puoi estendere solo un abstracclasse t.

Oggetti Singleton

Un singleton รจ una classe che viene istanziata una sola volta in un programma. Deriva da un modello di programmazione popolare e utile noto come "modello singleton". รˆ utile per creare istanze destinate ad avere una lunga durata e ad essere accedute frequentemente in tutto il programma, dove lo stato รจ parte integrante del coordinamento degli eventi in un sistema. Creare una tale classe in Scala รจ facile perchรฉ Scala fornisce un mezzo semplice per creare singleton utilizzando il object parola chiave.

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

รˆ quindi possibile fare riferimento a questo oggetto in tutto il programma con la garanzia che tutte le parti del programma visualizzino gli stessi dati, poichรฉ ne esiste una sola istanza.

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

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

In Scala non esiste il concetto di membri statici, motivo per cui si utilizzano oggetti singleton che si comportano come membri statici di una classe.

Classi implicite

Le classi implicite sono una funzionalitร  aggiunta nella versione 2.10 e vengono utilizzate principalmente per aggiungere nuove funzionalitร  a classi chiuse esistenti.

Migliori implicit La parola chiave deve essere definita in una classe, un oggetto o un tratto. Il costruttore primario di una classe implicita deve avere esattamente un argomento nel suo primo elenco di parametri. Puรฒ anche includere un elenco di parametri impliciti aggiuntivo.

Nell'esempio Scala riportato di seguito, รจ stata aggiunta una nuova funzionalitร  per sostituire le vocali di una stringa con *.

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

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

รˆ necessario importare la classe implicita nella classe in cui la si sta utilizzando.

import StringUtil.StringEnhancer

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

Programmazione orientata agli oggetti (OOP) vs. Programmazione funzionale (FP)

Nella programmazione orientata agli oggetti (OOP), i programmi vengono costruiti raggruppandoping dati e funzioni che operano su tali dati in unitร  altamente connesse. Gli oggetti trasportano i loro dati in campi e i metodi operano su di essi. In questo stile di programmazione, l'abstract principaletracLa funzione รจ costituita dai dati, perchรฉ i metodi creati sono progettati per operare sui dati.

Programmazione funzionale, d'altra parte, separa i dati dalle funzioni che operano su di essi. Ciรฒ consente agli sviluppatori di trattare le funzioni come l'assolutotraczione e forza motrice nella modellazione dei programmi.

Scala permette la programmazione funzionale trattando le funzioni come elementi di prima classe, consentendo loro di essere passate come valori ad altre funzioni e di essere restituite come valori. La combinazione di questi due paradigmi ha reso Scala un'ottima scelta per la creazione di software complessi in settori come la scienza dei dati.

Quadri importanti su Scala

Ecco alcuni framework importanti per Scala:

  • Giocare รจ un framework di applicazioni Web open source che utilizza Architettura MVCRilasciato nel 2007 e ora con licenza Apache, รจ diventato uno dei framework piรน popolari su GitHub entro il 2013. Aziende come LinkedIn, WalmartSamsung ed Eero utilizzano questo framework.
  • Sollevamento รจ un altro framework web gratuito scritto in Scala, lanciato nel 2007. Foursquare utilizza il framework Lift. Si tratta di un framework ad alte prestazioni e veloce da usare.
  • Akka Fornisce un toolkit per la creazione di applicazioni basate su messaggi, altamente concorrenti, distribuite e resilienti, sulla JVM.
  • Gatti รจ una biblioteca che fornisce abtraczioni per la programmazione funzionale.
  • Spark รจ un motore di analisi unificato per l'elaborazione di grandi quantitร  di dati, ampiamente utilizzato nei flussi di lavoro di big data e machine learning.

Supporto della concorrenza

  • In Scala, i valori sono immutabili per impostazione predefinita, il che rende il linguaggio molto adattabile agli ambienti concorrenti.
  • Scala possiede numerose caratteristiche che lo rendono ideale per le applicazioni concorrenti.
  • Futures e Promises semplificano l'elaborazione dei dati in modo asincrono, supportando cosรฌ il parallelismo.
  • Akka รจ un toolkit che utilizza il modello di concorrenza Actor. Gli attori agiscono quando ricevono messaggi.
  • Concorrenza utilizzando thread da Java รจ supportato anche in Scala.
  • L'elaborazione in streaming รจ un'altra fantastica funzionalitร  che consente l'elaborazione continua e in tempo reale dei dati.

Scala dispone di alcune delle migliori librerie concorrenti del mondo Java ecosistema:

  • Native Java thread.
  • Fibre provenienti da librerie come Vertx.
  • ZIO รจ una libreria che offre primitive per gestire la concorrenza e il calcolo asincrono.
  • Memoria transazionale software (STM) per le transazioni.
  • Future, che รจ integrato nel linguaggio Scala.

Java contro Scala

Ecco i principali differenze tra Java e Scala.

Scala Java
Piรน compatto e conciso. Blocchi di codice relativamente piรน grandi.
Progettato e sviluppato per essere sia orientato agli oggetti che funzionale. Supporta un'ampia varietร  di funzionalitร  di programmazione funzionale, come la concorrenza e l'immutabilitร . Originariamente sviluppato come linguaggio orientato agli oggetti, ha iniziato a supportare le funzionalitร  di programmazione funzionale nelle versioni piรน recenti. Tuttavia, non รจ ancora forte quanto Scala per la programmazione funzionale.
Utilizza il modello ad attori per supportare la concorrenza. Utilizza il modello basato su thread convenzionale per la concorrenza.
Supporta framework come Play e Lift. Supporta Spring, Grails e molti altri.
Supporta la valutazione pigra. Non supporta nativamente la valutazione pigra.
Nessun membro statico. Contiene membri statici.
Supporta il sovraccarico dell'operatore. Non supporta il sovraccarico degli operatori.
La compilazione del codice sorgente รจ relativamente lenta. La compilazione del codice sorgente รจ piรน veloce rispetto a Scala.
I tratti agiscono come Java 8 interfacce. Java 8 interfacce cercano di colmare il divario tra classi e interfacce.
A volte รจ necessario riscrivere il codice quando si aggiornano le versioni. In genere non รจ necessaria la riscrittura tra una versione e l'altra.
La sicurezza dei tipi offre una forte affidabilitร  del codice, ma non una garanzia assoluta di assenza di bug. Forte elettricitร  staticaping Contribuisce a ridurre numerosi difetti in fase di esecuzione.
Presenta alcune limitazioni di compatibilitร  con le versioni precedenti tra le versioni principali. Elevata compatibilitร  a lungo termine con le versioni precedenti.
OperaLe chiamate tors vengono trattate come chiamate di metodo. OperaI tors sono una sintassi speciale e non sono chiamate di metodo.
Supporta l'ereditarietร  multipla tramite tratti. Non supporta l'ereditarietร  multipla tramite classi; utilizza invece le interfacce.
Code รจ scritto in forma compatta. Code รจ scritto in una forma piรน prolissa.
Scala non contiene la parola chiave statica. Java contiene la parola chiave statica.

DOMANDE FREQUENTI

Scala ha una curva di apprendimento piรน ripida rispetto a Java perchรฉ unisce stili orientati agli oggetti e funzionali. Tuttavia, gli sviluppatori con Java Con l'esperienza, di solito si apprendono rapidamente le basi. Esercitarsi con piccoli progetti e utilizzare Scala REPL accelera l'apprendimento.

Sรฌ. Scala continua ad alimentare sistemi su larga scala presso aziende che utilizzano Akka, Sparke Kafka. La domanda rimane elevata nell'ingegneria dei dati, nel fintech e nei sistemi distribuiti, dove le prestazioni della JVM e la programmazione funzionale sono preziose.

Sรฌ. I moderni assistenti di programmazione AI comprendono la sintassi Scala, il sistema di tipi e framework come Akka e SparkContribuiscono a generare codice standard, suggeriscono modelli funzionali, spiegano gli errori del compilatore e rifattorizzano il codice, accelerando lo sviluppo sia per i principianti che per gli esperti.

Scala guida Apache SparkScala รจ il motore principale per l'elaborazione di grandi quantitร  di dati nelle pipeline di intelligenza artificiale. Librerie come Breeze, Smile e Figaro supportano il calcolo numerico, l'apprendimento automatico e la modellazione probabilistica, rendendo Scala un'ottima scelta per la data science in ambito produttivo.

Un `val` crea un'associazione immutabile che viene valutata immediatamente. Un `var` crea un'associazione mutabile che puรฒ essere riassegnata. Un `lazy val` posticipa la valutazione fino al primo accesso al valore, quindi memorizza il risultato nella cache per le letture successive.

Riassumi questo post con: