Tutorial Scala: esempio e codice del linguaggio di programmazione Scala

Riepilogo del tutorial su Scala

Questo tutorial su scala copre tutti gli aspetti e gli argomenti di scala. Imparerai da zero tutti i fondamenti come Cos'è scala, il processo di installazione di scala, i programmi Scala, le funzioni Scala, la valutazione pigra, l'interfaccia dei tipi, le classi e gli oggetti, l'ereditarietà, le astrazioni, Java e differenze di scala, ecc.

Cos'è Scala?

Scala è un linguaggio di programmazione tipizzato staticamente che incorpora la programmazione sia funzionale che orientata agli oggetti per aumentare la scalabilità delle applicazioni. Scala funziona principalmente su piattaforma JVM e può anche essere utilizzato per scrivere software per piattaforme native utilizzando Scala-Native e JavaCopione runtime tramite ScalaJs.

Scala è un linguaggio scalabile utilizzato per scrivere software per più piattaforme. Da qui il nome “Scala”. Questo linguaggio ha lo scopo di risolvere i problemi di Java pur essendo allo stesso tempo più conciso. Inizialmente progettato da Martin Odersky, è stato rilasciato nel 2003.

Perché imparare Scala

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

  • Scala è facile da imparare per i programmatori orientati agli oggetti, Java sviluppatori. Sta diventando una delle lingue più popolari negli ultimi anni.
  • Scala offre funzioni di prima classe per gli utenti
  • Scala può essere eseguito su JVM, aprendo così la strada all'interoperabilità con altri linguaggi.
  • È progettato per applicazioni simultanee, distribuite e resilienti basate su messaggi. È una delle lingue più esigenti di questo decennio.
  • È un linguaggio conciso e potente e può crescere rapidamente in base alla domanda dei suoi utenti.
  • È orientato agli oggetti e ha molte funzionalità di programmazione funzionale che forniscono agli sviluppatori molta flessibilità per codificare nel modo desiderato.
  • Scala offre molti tipi di anatra
  • Ha meno standard se vieni da Java
  • I framework Lift and Play scritti in Scala sono nella curva di crescita.

Come installare Scala

Per iniziare a scrivere programmi Scala, devi averlo installato sul tuo computer. Per fare ciò, dovrai visitare il loro sito https://www.scala-lang.org/download/ per scaricare l'ultima versione di Scala.

Seguendo il link, siamo condotti a due opzioni che possiamo scegliere per installare Scala sulle nostre macchine. Per questo tutorial su Scala, scaricheremo il IntelliJ IDEA.

Come installare Scala

Una volta visitato il collegamento per il download, troverai due versioni dell'IDE IntelliJ.

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

Come installare Scala

Passo 1) Seleziona Edizione comunitaria
Nella pagina, fai clic sul menu a discesa dell'edizione Community.

Ci presenta un'opzione per scaricare l'IDE IntelliJ insieme a JBR che contiene un'implementazione JDK (Java Development Kit) OpenJDK di cui Scala ha bisogno per compilare ed eseguire il codice.

Come installare Scala

Passo 2) Esegui l'installazione
Una volta scaricato IntelliJ, fai doppio clic su di esso per eseguire la procedura guidata di installazione e segui la finestra di dialogo.

Come installare Scala

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

Come installare Scala

Se per caso non hai scaricato quello con JDK, riceviamo comunque un messaggio in cui possiamo verificare di scaricarlo selezionando la casella di controllo.

Come installare Scala

Passo 4) Fare clic su Avanti
Lasciare le altre impostazioni predefinite così come sono e fare clic su Avanti.

Come installare Scala

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

Come installare Scala

È ancora necessario eseguire un passaggio aggiuntivo per aggiungere il plug-in Scala a IntelliJ; puoi farlo facendo clic sul menu a discesa del menu di configurazione situato nella parte inferiore destra dello schermo e selezionando l'opzione plug-in.

Come installare Scala

Come installare Scala

Nella scheda Marketplace, una ricerca per Scala presenterà il plugin come primo risultato sotto il tag Lingue.

Passo 6) Installa plugin
Fare clic su Installa, che farà sì che il plug-in inizi il download.

Come installare Scala

Passo 7) Riavviare l'IDE
Al termine del download, ti verrà richiesto di riavviare l'IDE in modo che il plug-in installato possa iniziare a funzionare.

Come installare Scala

Dopo il riavvio ti ritroverai nella stessa pagina di prima quando abbiamo eseguito l'IDE, ma questa volta abbiamo già installato il plugin Scala.

Programma Scala Ciao Mondo

Passo 1) Seleziona l'opzione Crea progetto, che ci porterà a una pagina in cui possiamo selezionare il tipo di linguaggio che utilizzerà il nostro progetto.

Programma Scala Ciao Mondo

Passo 2) scegli Scala selezionando la casella di controllo Scala e fai clic su Avanti.

Programma Scala Ciao Mondo

Passo 3) Seleziona una posizione in cui salvare il file dei nostri progetti e dai un nome al nostro progetto.

Programma Scala Ciao Mondo

Se la directory non esiste, IntelliJ ci chiederà di chiederci il permesso per creare la cartella. Accetta e fai clic su Fine. Verrai indirizzato al tuo progetto Scala, che attualmente non dispone di alcun codice Scala.

Ci vorrà del tempo per caricare alcuni indici quindi non preoccuparti se non riesci a fare immediatamente nulla mentre c'è una barra di avanzamento nella parte inferiore del tuo IDE, significa semplicemente che il tuo IDE sta caricando alcuni file necessari per eseguire Scala e aiuto con il completamento automatico dell'IDE.

Passo 4) Successivamente, faremo clic sulla scheda progetti a sinistra dell'IDE ed espanderemo in modo da poter vedere il contenuto del nostro progetto.

Programma Scala Ciao Mondo

Al momento il progetto è vuoto e contiene solo una cartella .idea e un file hello-world.iml generato dall'IDE. Il nostro punto di interesse è la cartella src. Src è dove memorizziamo il codice sorgente per il nostro progetto. È dove creeremo il nostro primo file Scala.

Passo 5) Fare clic con il tasto destro su src per aprire un menu per creare un nuovo file Scala.

Crea un nuovo file Scala

Creeremo quindi un nome per il file, in questo tutorial di Scala utilizzeremo hello e poi sceglieremo da un menu a discesa cosa inserire come contenuto del file Scala. Seleziona "Oggetto"

Programma Scala Ciao Mondo

Una volta fatto questo, avremo un file Scala che ha un oggetto Singleton che utilizzeremo per eseguire il nostro codice.

Programma Scala Ciao Mondo

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

Estendendo il nostro oggetto con App indica al compilatore quale codice eseguire quando avvia il programma. Immediatamente dopo aver esteso l'app, viene visualizzata una freccia verde sul lato sinistro, a indicare che ora puoi essere in grado di eseguire il tuo programma.

Programma Scala Ciao Mondo

Programma Scala Ciao Mondo

All'interno dell'oggetto Hello scriviamo una funzione println() che viene utilizzata per stampare il testo al suo interno sulla console. Eseguiremo il nostro codice facendo clic sulla freccia verde.

Facendo clic sulla freccia ci viene presentata l'opzione Esegui, ciao, facendo clic su di essa, il nostro codice inizierà la compilazione e dopo alcuni secondi vedremo i risultati del nostro programma stampati dalla console integrata nell'IDE IntelliJ.

Programma Scala Ciao Mondo

Ed ecco fatto, abbiamo installato con successo Scala ed eseguito il nostro primo programma.

Cosa puoi fare con Scala

  • Sviluppo web frontend con ScalaJS
  • Sviluppo mobile, entrambi Android Sviluppo e IOS – con Scala Native
  • Librerie lato server come HTTP4S, Akka-Http, Play Framework
  • Internet delle cose utilizzando
  • Sviluppo del gioco
  • NLP – Elaborazione del linguaggio naturale utilizzando una suite di librerie ScalaNLP
  • Testare tecniche di programmazione avanzate come la programmazione funzionale e la programmazione orientata agli oggetti
  • Costruisci un'applicazione di comunicazione altamente simultanea utilizzando una libreria per la JVM ispirata a Erlang
  • Usalo per l'apprendimento automatico utilizzando librerie come Figaro che esegue programmazione probabilistica e Apache Spark che

Funzioni anonime

Il linguaggio Scala ha funzioni anonime, chiamate anche letterali di funzione. Essendo Scala un linguaggio funzionale, spesso significa che gli sviluppatori suddividono grandi problemi in tanti piccoli compiti e creano molte funzioni per risolvere questi problemi. Per semplificare la creazione di funzioni, Scala contiene queste funzioni che possono essere istanziato senza nome. Possiamo assegnarli direttamente alle variabili o alle definizioni 'def' come mostrato nell'esempio Scala seguente:

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

Possiamo quindi utilizzare il modo normale in cui utilizziamo le funzioni passando loro i parametri seguenti.

multiplyByTwo(3)

//6

multiplyByThree(4)

//12

Questi metodi tornano utili quando vogliamo avere un codice pulito e conciso. Possiamo utilizzare funzioni anonime quando definiamo metodi che non sono grandi e non richiedono molto codice nel loro corpo. Sono molto semplici e non necessitano di una cerimonia per essere creati.

Questi metodi non sono limitati alle funzioni con argomenti e possono essere utilizzati per istanziare metodi che non accettano argomenti.

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

La maggior parte di queste funzioni anonime vengono utilizzate in altre parti del nostro codice in cui dobbiamo creare una funzione rapida sul posto.

Un altro motivo per cui queste funzioni vengono anche chiamate funzioni incorporate. L'utilizzo di funzioni anonime è un modello comune utilizzato in modo pervasivo nella libreria delle raccolte per eseguire azioni rapide su una raccolta.

Ad esempio, abbiamo il metodo filter che accetta una funzione inline/funzione anonima per creare un'altra raccolta con solo elementi che soddisfano i criteri che definiamo 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 i metodi che abbiamo come funzioni anonime sono quelli che controllano se il valore che otteniamo dalla lista è pari e dispari e restituiscono l'elemento.

//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 caratteri jolly laddove i parametri della nostra funzione anonima non hanno un nome. Per esempio

var timesTwo = (_:Int)*2

timesTwo(5)
//10

In questo scenario, non diamo un nome al parametro che stiamo passando. L'unica cosa che usiamo è un carattere di sottolineatura per rappresentarlo.

Valutazione pigra

La maggior parte dei linguaggi valutano in sequenza variabili e parametri di funzione, uno dopo l'altro. In Scala abbiamo una parola chiave chiamata lazy, che aiuta a gestire i valori che non vogliamo che vengano valutati finché non vengono referenziati.

Una variabile contrassegnata come pigra non verrà valutata dove è definita, operazione comunemente nota come valutazione impaziente, verrà valutata solo quando verrà fatta riferimento in un secondo momento nel codice.

Questo può essere utile quando valutare un valore potrebbe essere un calcolo costoso, se non è il caso che il valore sia sempre necessario, possiamo risparmiarci dall'eseguire un calcolo costoso che può rallentare il nostro software rendendo pigra la nostra variabile.

lazy val myExpensiveValue = expensiveComputation

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

Questo non è l'unico caso d'uso per le variabili pigre. Aiutano anche a gestire i problemi di dipendenza circolare nel codice.

Nel caso in cui le impostazioni siano false, potremmo non aver bisogno di utilizzare myExpensiveValue, il che può portarci a evitare di fare calcoli costosi che aiutano a garantire che gli utenti si divertano utilizzando la nostra applicazione poiché le altre loro esigenze possono essere calcolate correttamente senza travolgerli la RAM.

Nel caso in cui le impostazioni siano false, potremmo non aver bisogno di utilizzare myExpensiveValue, il che può portarci a evitare di fare calcoli costosi che aiutano a garantire che gli utenti si divertano utilizzando la nostra applicazione poiché le altre loro esigenze possono essere calcolate in modo appropriato senza sovraccaricarci la RAM.

La pigrizia aiuta anche con gli argomenti delle funzioni, in cui gli argomenti vengono utilizzati solo quando vengono referenziati all'interno della funzione. Questo concetto è chiamato parametri call-by-name.

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

Molti linguaggi utilizzano il metodo call-by-value per valutare gli argomenti. Il parametro passato tramite call-by-name verrà valutato solo quando necessario nel corpo della funzione e non verrà valutato prima. Una volta valutato, il valore viene memorizzato e può essere riutilizzato in seguito senza dover essere rivalutato. Un concetto noto come memorizzazione.

Digitare Inferenza

In Scala non è necessario dichiarare i tipi per ogni variabile creata. Questo perché il compilatore Scala può eseguire inferenze di tipo sui tipi in base alla valutazione del lato destro. Ciò consente al codice di essere più conciso: ci libera dalla necessità di scrivere boilerplate in cui il tipo previsto è ovvio

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

Funzione di ordine superiore

Una funzione di ordine superiore è una funzione che può accettare funzioni come argomenti e può restituire una funzione come tipo restituito. A Scala le funzioni sono considerate cittadini di prima classe. Usare queste funzioni in questo modo ci permette di essere molto flessibili nel tipo di programmi che possiamo realizzare. Possiamo creare funzioni in modo dinamico e fornire funzionalità in modo dinamico ad altre funzioni.

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

Nella funzione sopra, passiamo un int e una funzione che accetta un int e restituisce un int. Possiamo passare qualsiasi funzione di quella firma. Per firma intendiamo l'input e l'output di una funzione. Una firma Int=>Int significa che una funzione accetta un Int come input e restituisce un Int come output.

Una firma di ()=>Int significa che una funzione non accetta nulla in input e restituisce un Int come output. Un esempio di funzione del genere sarebbe quella che genera un int casuale per noi.

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

La funzione sopra ha una firma ()=>Int

Possiamo avere una funzione che ha una firma scala ()=>Unità. Ciò significa che le funzioni non accettano nulla e non restituiscono un tipo. La funzione potrebbe eseguire una sorta di calcolo cambiando qualcosa in qualcosa di predeterminato.

Questi tipi di metodi, tuttavia, non sono incoraggiati, poiché sembrano essere una scatola nera che può influenzare un sistema in modi sconosciuti. Sono anche non testabili. Avere tipi di input e output espliciti ci consente di ragionare su ciò che fa la nostra funzione.

Anche una funzione di ordine superiore può restituire una funzione.

Ad esempio, potremmo creare un metodo che creerà una funzione di potenza, ovvero prenderà un numero e gli applicherà una potenza.

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

La funzione precedente accetta un int. Il nostro tipo restituito è una funzione anonima che accetta un Int x, * utilizziamo l'int x come argomento per la funzione power.

curry

In Scala possiamo convertire una funzione che accetta due argomenti in una che accetta un argomento alla volta. Quando passiamo un argomento, lo applichiamo parzialmente e finiamo con una funzione che accetta un argomento per completare la funzione. Il currying ci consente di creare funzioni aggiungendo parzialmente alcuni argomenti.

Questo può essere utile per creare funzioni dinamicamente prima di avere un set completo di argomenti

def multiply two numbers(n:Int)(m:Int): Unit ={
  return n * m
}

Se dobbiamo creare una funzione che moltiplichi per un numero specifico, non abbiamo bisogno di creare un altro metodo di moltiplicazione.

Possiamo semplicemente chiamare .curried sulla nostra funzione sopra e ottenere una funzione che accetta prima un argomento e restituisce una funzione parzialmente applicata

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

var multiplyByFive = multiplyTwoNumbers(5) 

multiplyByFive(4)

//returns 20

Pattern Matching

Scala ha un potente meccanismo integrato che ci aiuta a verificare se una variabile soddisfa determinati criteri, proprio come faremmo in un'istruzione switch in Java o in una serie di istruzioni if/else. Il linguaggio ha una corrispondenza di modelli che possiamo usare per verificare se una variabile è di un tipo particolare. La corrispondenza dei modelli in Scala è potente e può essere utilizzata per destrutturare i componenti che hanno un metodo unapply per ottenere i campi che ci interessano direttamente dalla variabile che stiamo corrispondendo.

Il pattern match di Scala fornisce anche una sintassi più gradevole rispetto all'istruzione switch.

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

Confrontiamo la nostra variabile con un insieme di opzioni e quando la variabile che stiamo abbinando soddisfa i criteri, l'espressione sul lato destro della freccia grossa (=>) valuta e viene restituita come risultato della corrispondenza.

Usiamo un carattere di sottolineatura per individuare i casi che non hanno corrispondenza nel nostro codice. Rispecchia il comportamento del caso predefinito quando si ha a che fare con le istruzioni 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 _ => //case we have a type we don't recognize do sth else
}

Nel codice sopra, puoi scoprire il tipo della variabile myItem e in base a ciò diramarsi verso un codice specifico.

La corrispondenza del modello controlla se la variabile corrisponde

Il carattere di sottolineatura funziona come un segnaposto che corrisponde a qualsiasi altra condizione che non corrisponde agli altri elementi nelle istruzioni case precedenti. Prendiamo una variabile myItem e chiamiamo il metodo match.

  • controlliamo se myItem è vero utilizzando ed eseguiamo un po' di logica sul lato destro della freccia grassa “=>”.
  • usiamo il carattere di sottolineatura per abbinare tutto ciò che non corrisponde a nessuna delle istruzioni case che abbiamo definito nel codice.

Con le classi Case possiamo anche andare oltre e destrutturare la classe per ottenere campi all'interno dell'oggetto.

Usando la parola chiave sealed per definire le nostre classi, otteniamo il vantaggio di avere il compilatore che controlla in modo esaustivo i casi con cui proviamo a confrontarci e ci avvisa se dimentichiamo di gestirne uno particolare.

Immutabilità

È possibile creare valori che non possono essere modificati da altre funzioni in Scala utilizzando la parola chiave val. Ciò è ottenuto in Java utilizzando la parola chiave finale. In Scala, lo facciamo utilizzando la parola chiave val quando creiamo una variabile invece di utilizzare var, che è l'alternativa che useremmo per creare una variabile mutabile.

Una variabile definita utilizzando la parola chiave val è di sola lettura, mentre una definita con var può essere letta ed essere modificata da altre funzioni o arbitrariamente dall'utente nel codice.

var changeableVariable = 8

changeableVariable =10
//the compiler doesn't complain, and the code compiles successfully

println(changeableVariable)
//10

val myNumber = 7

myNumber = 4

//if we try this the code won't compile

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

Perché usare l'Immutabilità?

L'immutabilità ci aiuta a impedire che il codice e altri programmatori modifichino i nostri valori inaspettatamente, il che porterebbe a risultati inaspettati se intendono utilizzare il valore che memorizziamo possono invece farne una copia. In questo modo si prevengono i bug che possono essere causati da più attori che modificano la stessa variabile.

Classi e oggetti

Sappiamo tutti che gli oggetti sono entità del mondo reale e la classe è un modello che definisce gli oggetti. Le classi hanno sia stato che comportamenti. Gli stati sono valori o variabili. I comportamenti sono i metodi in Scala.

Esaminiamo come definire una classe, crearne un'istanza e utilizzarla utilizzando Scala.

Qui, la classe chiamata Rectangle, che ha due variabili e due funzioni. È inoltre possibile utilizzare i parametri leb direttamente come campi nel programma. Hai un oggetto che ha un metodo main e ha istanziato 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 rectangle with length as $length and breadth as  $breadth"
  }
object RectObject {
  def main(args: Array[String]) {
    val rect = new Rectangle(4, 5)
    println(rect.toString)
    println(rect.getArea)    
  }
}

Tutti i campi e il metodo sono pubblici per impostazione predefinita in Scala. È essenziale utilizzare l'override perché il metodo toString è definito per Object in Scala.

Eredità

Scala ha diversi tipi di ereditarietà (come singola, multilivello, multipla, gerarchica, ibrida) che hanno molto in comune con le forme tradizionali trovate in Java. Puoi ereditare sia dalle classi che dai tratti. Puoi ereditare i membri di una classe in un'altra classe usando la parola chiave "extends". Ciò consente la riusabilità.

È possibile ereditare da una o più classi. È anche possibile ereditare da sottoclassi che a loro volta hanno le proprie superclassi, creando una gerarchia di ereditarietà nel processo.

Nell'esempio Scala seguente, la classe Base è Circle e la classe derivata è Sphere. Un cerchio ha un valore chiamato raggio, che viene ereditato dalla 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 
    }
  }

Astrazione

In Scala, possiamo creare metodi astratti e campi membro utilizzando classi e tratti astratti. All'interno di classi e tratti astratti, possiamo definire campi astratti senza necessariamente 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 la classe astratta. Puoi utilizzare i tratti per creare contratti su ciò che la nostra applicazione dovrebbe essere in grado di fare e quindi implementare tali metodi in un secondo momento.

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

In questo modo, possiamo pianificare come apparirà la nostra applicazione senza implementare i metodi che possono aiutarci a immaginare come appariranno i vari metodi. Segue un modello noto come programmazione delle astrazioni e non dell'effettiva implementazione.

La classe preceduta dalla parola chiave abstract può contenere sia metodi astratti che non astratti. Tuttavia, le eredità multiple non sono supportate nella classe astratta. Quindi, puoi estendere al massimo una classe astratta.

Oggetti Singleton

Un Singleton è una classe di cui 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 a durare a lungo e a cui si accederà comunemente in tutto il programma, il cui stato è parte integrante del coordinamento degli eventi di un sistema. Creare una classe di questo tipo in Scala è facile poiché Scala ci fornisce un mezzo semplice per creare singleton usando la parola chiave object.

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

Possiamo quindi fare riferimento a questo oggetto in tutto il nostro programma con la garanzia che tutte le parti del nostro programma vedranno 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
}

Il concetto di membro statico non è presente in Scala, questo è il motivo per cui è necessario utilizzare oggetti singleton, che agiscono come membri statici di una classe.

Classi implicite

Le classi implicite sono la nuova funzionalità aggiunta dopo la versione 2.1. Si tratta principalmente di aggiungere nuove funzionalità alle classi chiuse.

La parola chiave implicita dovrebbe essere definita in una classe, oggetto o tratto. Il costruttore primario di una classe implicita dovrebbe avere esattamente un argomento nel suo primo elenco di parametri. Può anche includere un ulteriore elenco di parametri impliciti.

Nell'esempio Scala seguente, viene 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]", "*")
  }
}

Devi importarlo nella classe in cui lo stai utilizzando.

import StringUtil.StringEnhancer

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

Programmazione orientata agli oggetti (OOP) e programmazione funzionale (FP)

In OOP i programmi sono costruiti raggruppando i dati e le funzioni che operano su tali dati in unità altamente connesse. Gli oggetti trasportano i loro dati nei campi e nei metodi che operano su di essi. In questo stile di programmazione, l'astrazione principale sono i dati poiché i metodi creati sono destinati a operare sui dati.

Programmazione funzionale, d'altro canto, separa i dati e le funzioni che operano sui dati. Ciò consente agli sviluppatori di trattare le funzioni come astrazione e forza trainante durante la modellazione dei programmi.

Scala consente la programmazione funzionale avendo funzioni come cittadini di prima classe, consentendo loro di essere passati come valori ad altre funzioni e restituiti a loro volta come valori. La combinazione di questi due paradigmi ha reso Scala un'ottima scelta nella creazione di software complessi in vari settori, come quello della scienza dei dati.

Quadri importanti su Scala

Ecco alcuni importanti quadri di Scala

  • Giocare è un framework di applicazioni Web open source che utilizza Architettura MVC. Rilasciato nel 2007 e ora concesso in licenza con Apache, è diventato il framework più popolare su GitHub nel 2013. Aziende come LinkedIn, Walmart, Samsung, Eero utilizzano questo framework.
  • Sollevamento è un altro framework web gratuito scritto in Scala lanciato nel 2007. Foursquare utilizza il framework Lift. È altamente performante e più veloce da costruire.
  • Akka
  • Gatti
  • Spark

Supporto della concorrenza

  • I valori in Scala sono immutabili per impostazione predefinita. Ciò lo rende molto adattivo all'ambiente simultaneo.
  • Ci sono molte funzionalità in Scala che lo rendono ideale per applicazioni simultanee.
  • Futures e Promises semplificano l'elaborazione dei dati in modo asincrono, supportando così il parallelismo.
  • Akka: toolkit che utilizza il modello di concorrenza degli attori. Esistono numerosi attori che agiscono quando ricevono messaggi.
  • Concorrenza utilizzando thread da Java può essere supportato anche in Scala.
  • L'elaborazione del flusso è un'altra grande 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 fili
  • Fibre da librerie come Vertex
  • ZIO – una libreria che dispone di primitive per aiutarci a gestire la concorrenza e il calcolo asincrono
  • STM – Transazione
  • Futuro – integrato nel linguaggio Scala

Java contro Scala

Ecco i principali differenza fra Java e Scala.

Scala Java
Più compatto e conciso Pezzi di codice relativamente più grandi
Progettato e sviluppato per essere un linguaggio orientato sia agli oggetti che alle funzioni.
Supporta un'ampia varietà di funzionalità di programmazione funzionale come concorrenza e immutabilità.
Originariamente sviluppato come linguaggio orientato agli oggetti e ha iniziato a supportare funzionalità di programmazione funzionale negli ultimi giorni. Non è ancora forte come linguaggio di programmazione funzionale.
Utilizza il modello di attore per supportare la concorrenza che è moderna Utilizza il modello basato su thread convenzionale per la concorrenza.
Supporta strutture: gioca, solleva Supporta Spring, Grails e molto altro
Supporta la valutazione pigra Non supporta la valutazione pigra
Nessun membro statico Contiene membri statici
Supporta l'overload dell'operatore Non supporta l'overload dell'operatore
La compilazione del codice sorgente è relativamente lenta La compilazione del codice sorgente è più veloce di Scala
Tratti: comportarsi come Java 8 interfacce Java 8 interfacce cercano di colmare il divario tra classi e interfacce
È necessaria una riscrittura Non è necessaria la riscrittura
Nessuna garanzia sui codici privi di bug Garanzia completa di difetti minori
Supporta la compatibilità con le versioni precedenti. Scala non supporta la compatibilità con le versioni precedenti.
Operai tori sono trattati diversamente in Java e non sono chiamate di metodo. Tutti gli operatori sulle voci utilizzano un metodo chiamato in Scala.
Supporta più eredità utilizzando classi ma non classi astratte Non supporta eredità multiple utilizzando classi, ma tramite interfacce
Il codice è scritto in una forma compatta. Il codice è scritto in forma lunga.
Scala non contiene la parola chiave statica. Java contiene la parola chiave statica.

Sommario

In questo tutorial hai imparato come iniziare con Scala. Hai anche imparato le caratteristiche funzionali e orientate agli oggetti. Hai anche scoperto le somiglianze e le differenze tra Java e Scala. Questo tutorial dovrebbe averti aiutato con un'ampia varietà di esempi ben dimostrati.