Scala Tutorial

⚡ Rezumat inteligent

Tutorialul Scala prezintă un limbaj de programare bazat pe JVM, cu tipizare statică, care combină programarea orientată pe obiecte și cea funcțională. Ghidul acoperă instalarea, sintaxa, caracteristicile de bază și framework-urile care fac Scala ideal pentru construirea de aplicații moderne concurente, scalabile și concise.

  • 🔘 Paradigma hibridă: Scala combină programarea orientată pe obiecte cu cea funcțională pe JVM, permițând dezvoltatorilor să combine imutabilitatea, funcțiile de primă clasă și ierarhiile tradiționale de clase.
  • ☑️ Sintaxă concisă: Inferența de tip, funcțiile anonime și potrivirea de șabloane reduc utilizarea standard în comparație cu Java în timp ce keeping codul expresiv și lizibil.
  • ✅ Configurare cu IntelliJ: Instalați IDE-ul Community Edition, adăugați pluginul Scala și creați un obiect care extinde App pentru a rula primul program Hello World.
  • 🧪 Blocuri de construcție funcționale: Evaluarea leneșă, currying-ul, funcțiile de ordin superior și imutabilitatea prin val permit cod curat și previzibil.
  • 🛠️ Concurență și cadre de lucru: Actori Akka, Futures, Play, Lift și Spark fac din Scala o alegere puternică pentru sisteme distribuite, aplicații web și inginerie de date.

Scala Tutorial

Ce este Scala?

Scala este un limbaj de programare cu tipizare statică care combină programarea orientată pe obiecte și cea funcțională pentru a îmbunătăți scalabilitatea aplicațiilor. Scala rulează în principal pe platforma JVM, iar dezvoltatorii îl pot folosi și pentru a scrie software pentru platforme native prin Scala-Native sau pentru browser prin ScalaJs și JavaScenariu timpul de rulare.

Scala este un limbaj scalabil folosit pentru a construi software pentru platforme multiple, exact de unde și-a primit numele. Limbajul a fost conceput pentru a rezolva mai multe dintre problemele de verbositate întâlnite în Java rămânând concis. Martin Odersky a proiectat Scala, iar prima lansare publică a apărut în 2004.

De ce să înveți Scala

Iată principalele motive pentru a învăța limbajul de programare Scala:

  • Scala este ușor de învățat pentru programatorii orientați pe obiecte și Java dezvoltatori și a devenit unul dintre limbajele populare din ultimii ani.
  • Scala oferă funcții de primă clasă pentru utilizatori.
  • Scala poate fi executat pe FMV, deschizând calea pentru interoperabilitate cu alte limbaje.
  • Este conceput pentru aplicații concurente, distribuite și rezistente, bazate pe mesaje, ceea ce îl face unul dintre cele mai căutate limbaje de programare ale acestui deceniu.
  • Este un limbaj concis și puternic, care se poate dezvolta rapid în funcție de cerințele utilizatorilor săi.
  • Este orientat pe obiecte și include multe caracteristici funcționale de programare, oferind dezvoltatorilor multă flexibilitate în modul în care scriu cod.
  • Scala oferă Duck Typing prin tipuri structurale.
  • Are mai puține exemple standard decât Java.
  • Framework-urile Lift and Play, scrise în Scala, continuă să se maturizeze și să crească în popularitate.

Cum se instalează Scala

Pentru a începe să scrieți programe Scala, trebuie să îl aveți instalat pe computer. Pentru a face acest lucru, vizitați site-ul oficial la https://www.scala-lang.org/download/ pentru a descărca cea mai recentă versiune de Scala.

Urmând linkul, vi se prezintă două opțiuni pentru instalarea Scala. Pentru acest tutorial Scala, vom folosi IntelliJ IDEA, care oferă suport excelent Scala imediat după deschidere.

Cum se instalează Scala

După ce accesați linkul de descărcare, veți găsi două ediții ale IDE-ului IntelliJ.

Pentru acest tutorial Scala, vom descărca Community Edition, care este gratuită și include tot ce aveți nevoie pentru a scrie programe Scala.

Pagina de descărcare a ediției comunitare IntelliJ

Pas 1) Selectați Ediția Comunitară.
Pe pagină, faceți clic pe meniul derulant din Ediția Comunitară.

Prezintă o opțiune de descărcare a IDE-ului IntelliJ împreună cu JBR, care conține o implementare JDK (Java Kit de dezvoltare) cum ar fi OpenJDK, de care Scala are nevoie pentru a compila și rula cod.

Descărcați IntelliJ cu JBR

Pas 2) Rulați instalarea.
După ce descărcați IntelliJ, faceți dublu clic pe programul de instalare și urmați instrucțiunile expertului de pe ecran.

Expertul de instalare IntelliJ

Pas 3) Selectați o locație.
Alegeți o locație pentru a instala IDE-ul.

Alegeți folderul de instalare

Dacă nu ați descărcat pachetul cu JDK-ul, programul de instalare vă solicită în continuare să adăugați JDK-ul printr-o casetă de selectare în timpul configurării.

Caseta de selectare JDK în timpul instalării

Pas 4) Faceți clic pe Următorul.
Lăsați celelalte setări implicite așa cum sunt și faceți clic pe Următorul.

Opțiuni implicite ale instalatorului

Programul Scala Hello World

Pas 5) Faceți clic pe pictograma de pornire.
După finalizarea instalării, rulați IntelliJ IDE făcând clic pe pictograma sa de pornire din meniul Start, ca pe o aplicație obișnuită.

Ecran de bun venit IntelliJ

Încă trebuie să adăugați pluginul Scala la IntelliJ. Faceți clic pe meniul derulant din meniul de configurare din partea dreaptă jos a ecranului și selectați opțiunea Pluginuri.

Meniu de configurare pentru pluginuri

Piața pluginurilor IntelliJ

În fila Marketplace, căutați Scala. Pluginul apare ca primul rezultat sub eticheta Languages.

Pas 6) Instalați pluginul.
Faceți clic pe Instalare pentru a începe descărcarea pluginului Scala.

Instalați pluginul Scala

Pas 7) Reporniți IDE-ul.
După finalizarea descărcării, vi se va solicita să reporniți IDE-ul pentru ca pluginul instalat să poată începe să funcționeze.

Reporniți promptul IntelliJ

După repornire, reveniți la aceeași pagină ca înainte, dar acum pluginul Scala este instalat și gata.

Pas 8) Selectați Creare proiect, ceea ce duce la o pagină unde puteți alege limba pentru proiect.

Creați un proiect nou în IntelliJ

Pas 9) Alegeți Scala bifând caseta de selectare Scala și făcând clic pe Următorul.

Selectați limba Scala

Pas 10) Selectați o locație pentru a salva fișierul proiectului și dați un nume proiectului.

Denumiți și localizați proiectul

Dacă directorul nu există, IntelliJ solicită permisiunea de a crea folderul. Acceptați și faceți clic pe Finalizare. Veți fi apoi direcționat către proiectul dvs. Scala, care în prezent nu conține niciun cod Scala.

Încărcarea indexurilor durează ceva timp, așa că nu vă faceți griji dacă nu puteți interacționa cu IDE-ul în timp ce o bară de progres este afișată în partea de jos. IDE-ul încarcă fișierele necesare pentru a rula Scala și a oferi completare automată.

Pas 11) Faceți clic pe fila Proiect din stânga IDE-ului și extindeți-o pentru a vedea conținutul proiectului.

Extindeți fila proiectului

În acest moment, proiectul este gol și conține doar un folder .idea și un fișier hello-world.iml generat de IDE. Punctul de interes este folderul src, care conține codul sursă al proiectului. Aici creați primul fișier Scala.

Pas 12) Faceți clic dreapta pe src pentru a deschide un meniu și a crea un nou fișier Scala.

Creați un nou fișier Scala

Alegeți un nume pentru fișier. Pentru acest tutorial Scala, utilizați Alo, apoi alegeți Obiect din meniul derulant pentru tipul de conținut al fișierului Scala.

Alegeți tipul de obiect

După ce faci asta, ai un fișier Scala care conține un obiect singleton pe care îl vei folosi pentru a rula codul.

Obiectul Singleton a fost creat

Acum, că aveți un fișier Scala cu un obiect Hello, scrieți primul program extinzând obiectul creat folosind cuvântul cheie App.

Extinderea obiectului cu App îi spune compilatorului ce cod să ruleze la pornirea programului. Imediat după extinderea App, apare o săgeată verde în partea stângă, indicând faptul că programul poate fi rulat.

Săgeată de rulare în IntelliJ

Opțiunea Executare Salut

În interiorul obiectului Hello, scrieți funcția println() pentru a afișa textul în consolă. Rulați programul făcând clic pe săgeata verde.

Dacă dați clic pe săgeată, apare opțiunea Run Hello (Run Hello). Selectarea acesteia compilează codul, iar după câteva secunde, rezultatul programului apare în consola IntelliJ.

Ieșirea Hello World în consolă

Ați instalat cu succes Scala și ați rulat primul program.

Ce poți face cu Scala

Scala este utilizat pe scară largă în multe domenii datorită flexibilității și interoperabilității JVM. Cazurile de utilizare comune includ:

  • Dezvoltare web frontend cu ScalaJS.
  • Dezvoltare mobilă pentru Android și iOS cu Scala Native.
  • Biblioteci pe server, cum ar fi HTTP4S, Akka-Http și Play Framework.
  • Aplicații ale Internetului Lucrurilor (IoT).
  • Dezvoltarea jocului.
  • Prelucrarea limbajului natural folosind suita de biblioteci ScalaNLP.
  • Practicarea împreună a unor tehnici avansate, cum ar fi programarea funcțională și programarea orientată pe obiecte.
  • Aplicații de comunicare concurentă ridicată folosind actori, o bibliotecă pentru JVM inspirată de Erlang.
  • Învățare automată cu biblioteci precum Figaro pentru programare probabilistică și Apache Spark pentru prelucrarea datelor la scară largă.

Funcții anonime

Limbajul Scala suportă funcții anonime, numite și literali de funcțieDeoarece Scala este un limbaj funcțional, dezvoltatorii împart adesea problemele mari în mai multe sarcini mici și creează mai multe funcții. Pentru a facilita acest lucru, Scala permite ca funcțiile să fie instanțiat fără numeLe puteți atribui direct variabilelor sau definițiilor folosind def, așa cum se arată în următorul exemplu Scala:

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

Apoi le puteți utiliza ca funcții obișnuite prin transmiterea parametrilor:

multiplyByTwo(3)
//6

multiplyByThree(4)
//12

Aceste metode sunt utile atunci când doriți cod curat și concis. Funcțiile anonime sunt utile atunci când definiți metode mici care nu necesită mult cod în corpul lor. Sunt foarte simple și nu necesită nicio ceremonie pentru a fi create.

Aceste metode nu se limitează la funcții cu argumente și pot fi folosite pentru a instanția metode care nu primesc argumente.

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

Majoritatea acestor funcții anonime sunt utilizate în alte părți ale codului unde este nevoie de o funcție rapidă implementată. Din acest motiv, ele sunt denumite și funcții inlineUtilizarea funcțiilor anonime este un model comun care apare în biblioteca de colecții pentru a efectua acțiuni rapide asupra unei colecții.

De exemplu, metoda de filtrare preia o funcție inline pentru a crea o altă colecție doar cu elementele care îndeplinesc criteriile definite în funcția anonimă.

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)

Aici, funcțiile anonime verifică dacă valoarea din listă este pară sau impară și returnează elementul corespunzător.

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

În Scala, este posibilă și utilizarea wildcard-urilor unde parametrul funcției anonime nu este denumit. De exemplu:

var timesTwo = (_:Int) * 2

timesTwo(5)
//10

În acest scenariu, nu denumiți parametrul. Sublinierea este utilizată pentru a-l reprezenta.

Evaluare leneșă

Majoritatea limbajelor evaluează secvențial variabilele și parametrii funcțiilor, unul după altul. În Scala, cuvântul cheie lazy ajută la gestionarea valorilor pe care nu doriți să le evaluați până când nu sunt făcute referire la ele.

O variabilă marcată ca leneșă nu este evaluată acolo unde este definită, ceea ce este cunoscut sub numele de evaluare entuziasmată. Este evaluată doar atunci când este referențiată ulterior în cod.

Acest lucru poate fi util atunci când evaluarea unei valori ar fi un calcul costisitor. Dacă valoarea nu este întotdeauna necesară, te scutești de executarea unui calcul costisitor care poate încetini software-ul prin faptul că făcea variabila „lenny”.

lazy val myExpensiveValue = expensiveComputation

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

Acesta nu este singurul caz de utilizare pentru variabilele lenny. Ele ajută și la gestionarea dependențelor circulare din cod.

Dacă stegulețul setărilor este fals, nu este nevoie să utilizați myExpensiveValue, ceea ce vă scutește de efectuarea unui calcul costisitor. Acest lucru ajută la asigurarea unei experiențe fluide pentru utilizatori, deoarece resursele nu sunt irosite pe valori care nu sunt niciodată citite.

Lenea ajută și la argumentele funcțiilor, unde argumentele sunt folosite doar atunci când sunt referențiate în interiorul funcției. Acest concept se numește parametri apel-după-nume.

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

Multe limbaje folosesc abordarea apel-după-valoare pentru evaluarea argumentelor. Un parametru transmis prin apel-după-nume este evaluat doar atunci când este necesar în interiorul corpului funcției. Odată ce valoarea este evaluată, aceasta este stocată și poate fi reutilizată ulterior fără reevaluare, un concept cunoscut sub numele de memoizare.

Tip Inferență

În Scala, nu trebuie să declarați tipuri pentru fiecare variabilă pe care o creați, deoarece compilatorul Scala poate deduce tipuri din partea dreaptă a unei expresii. Acest lucru permite codului dvs. să fie mai concis și vă scutește de scrierea unor coduri standard unde tipul așteptat este evident.

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

Funcție de ordin superior

O funcție de ordin superior este o funcție care poate lua funcții ca argumente și poate returna o funcție ca tip de retur. În Scala, funcțiile sunt considerate cetățeni de primă clasă. Utilizarea funcțiilor în acest mod vă permite să fiți foarte flexibili în ceea ce privește tipurile de programe pe care le puteți construi. Puteți crea funcții dinamic și puteți furniza funcționalități dinamic altor funcții.

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

În funcția de mai sus, transmiteți un Int și o funcție care ia o Int și returnează un IntPuteți transmite orice funcție a acelei semnături. Prin semnătură, ne referim la intrarea și ieșirea unei funcții. O semnătură a Int => Int înseamnă că o funcție primește un număr întreg (Int) ca intrare și returnează un număr întreg (Int) ca ieșire.

O semnătură a () => Int înseamnă că o funcție nu primește nimic ca intrare și returnează un număr întreg ca ieșire. Un exemplu de astfel de funcție este una care generează un număr întreg aleatoriu.

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

Funcția de mai sus are o semnătură () => Int.

O funcție poate avea și o semnătură () => UnitAceasta înseamnă că funcția nu acceptă nimic și nu returnează un tip. În schimb, funcția poate schimba o stare sau poate efectua o acțiune predeterminată.

Aceste tipuri de metode nu sunt încurajate deoarece pot acționa ca o cutie neagră care afectează un sistem în moduri necunoscute. De asemenea, sunt mai greu de testat. Tipurile explicite de intrare și ieșire vă permit să raționați despre ceea ce face funcția dumneavoastră.

O funcție de ordin superior poate, de asemenea, returna o funcție. De exemplu, ați putea crea o metodă care returnează o funcție de generare a puterii, una care ia un număr și îi aplică o putere.

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

Funcția de mai sus primește un număr întreg (Int). Tipul său de returnare este o funcție anonimă care primește un număr întreg (Int). x și o folosește ca argument pentru funcția de putere.

curry

În Scala, poți converti o funcție care primește două argumente într-una care primește câte un argument odată. Când transmiți un argument, îl aplici parțial și obții o funcție care primește argumentul rămas pentru a finaliza apelul. Currying îți permite să construiești funcții prin adăugarea parțială a unor argumente.

Acest lucru este util pentru crearea dinamică a funcțiilor înainte de a avea un set complet de argumente.

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

Dacă aveți nevoie de o funcție care înmulțește cu un anumit număr, nu este nevoie să creați o altă metodă de înmulțire. Puteți aplica un argument funcției curried și reutiliza rezultatul:

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

var multiplyByFive = multiplyTwoNumbers(5) _

multiplyByFive(4)

//returns 20

Potrivire de model

Scala are un mecanism puternic încorporat care vă ajută să verificați dacă o variabilă îndeplinește anumite criterii, la fel ca o instrucțiune switch în Java sau un lanț de instrucțiuni if/else. Limbajul acceptă potrivirea de modele, pe care o puteți utiliza pentru a verifica dacă o variabilă este de un anumit tip. Potrivirea de modele în Scala este puternică și poate destructura componentele care au un unapply metodă pentru a obține câmpurile care vă interesează direct din variabila care este potrivită.

Potrivirea modelelor Scala oferă și o sintaxă mai plăcută decât o instrucțiune switch.

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

Comparați variabila cu un set de opțiuni. Când variabila îndeplinește criteriile, expresia din partea dreaptă a săgeții groase (=>) se evaluează și returnează rezultatul potrivirii.

Sublinierea identifică cazurile care nu se potrivesc în cod, oglindind comportamentul cazului implicit dintr-o instrucțiune 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
}

În codul de mai sus, puteți detecta tipul de myItem variabilă și, pe baza acesteia, se ramifică către un cod specific.

Potrivirea de modele verifică dacă variabila corespunde fiecărui caz în ordine.

Sublinierea funcționează ca un substituent care corespunde oricărei condiții pe care celelalte instrucțiuni de caz nu o corespund. Luați o variabilă myItem și sună la match metodă.

  • Verifica vremea myItem is true și rulează logica în partea dreaptă a săgeții groase „=>”.
  • Folosește sublinierea pentru a potrivi orice element care nu corespunde niciuneia dintre instrucțiunile de caz definite în cod.

Cu clasele de caz, puteți destructura clasa pentru a extraccâmpuri t în interiorul obiectului.

Prin utilizarea funcției sealed cuvânt cheie pentru a defini clase, aveți avantajul ca compilatorul să verifice exhaustiv cazurile pe care încercați să le potriviți și să vă avertizeze dacă uitați să gestionați unul.

Imuabilitate

Este posibil să creați valori care nu pot fi modificate de alte funcții în Scala utilizând val cuvânt cheie. Acest lucru se realizează în Java folosind final cuvânt cheie. În Scala, folosești un val atunci când se creează o variabilă în loc de var, care este alternativa pentru variabilele mutabile.

O variabilă definită folosind val cuvântul cheie este doar pentru citire, în timp ce unul definit cu var pot fi citite și modificate ulterior de alte funcții sau de către utilizator în cod.

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

Încercând să atribui o valoare myNumber după ce a declarat-o ca fiind val generează o eroare la compilare: „reatribuire la val.”

De ce să folosiți Imutabilitatea?

Imutabilitatea ajută la prevenirea modificării neașteptate a valorilor de către cod și alți programatori, ceea ce ar duce la rezultate imprevizibile. Dacă utilizatorii unei valori trebuie să o modifice, pot face o copie. În acest fel, se previn erorile cauzate de modificarea aceleiași variabile de către mai mulți actori.

Clase și obiecte

Obiectele sunt entități din lumea reală, iar o clasă este un șablon care definește obiectele. Clasele au atât stare, cât și comportamente. Stările sunt fie valori, fie variabile. Comportamentele sunt metodele din Scala.

Următoarea secțiune arată cum se definește o clasă, cum se instanțiază și cum se utilizează în Scala.

Iată o clasă numită Rectangle care are două valori și două funcții. De asemenea, puteți utiliza parametrii l și b direct ca și câmpuri în program. Aveți un obiect care are o metodă principală și instanțiază clasa cu două valori.

Exemplu:

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

Toate câmpurile și metodele sunt publice în mod implicit în Scala. Este esențial să se utilizeze override deoarece toString este deja definit pentru fiecare obiect din Scala.

Moştenire

Scala are mai multe tipuri de moștenire (single, multi-nivel, multiplă, ierarhică și hibridă) care au multe în comun cu formele tradiționale găsite în JavaPoți moșteni atât de la clase, cât și de la trăsături. Moștenești membrii unei clase într-o altă clasă folosind cuvântul cheie extendsAcest lucru permite reutilizarea.

Este posibil să moștenești de la o clasă sau de la mai multe clase. De asemenea, este posibil să moștenești de la subclase care au propriile superclase, creând o ierarhie de moștenire în acest proces.

În exemplul Scala de mai jos, clasa de bază este Circle, iar clasa derivată este SphereUn cerc are o valoare numită rază, care este moștenită în clasa Sphere. Metoda calcArea este suprascris folosind cuvântul cheie override.

Exemplu:

class Circle {
  val radius = 5
  def calcArea = {
    println(radius * radius)
  }
}
class Sphere extends Circle {
 override def calcArea = {
    println(radius * radius * radius)
  }
}
  object SphereObject {
    def main(args : Array[String]) {
      new Sphere().calcArea
    }
  }

AbstracTION

În Scala, poți crea abdomenetracmetode t și câmpuri de membri folosind abstracClase și trăsături t. Abdomenul interiortracclase și trăsături, poți defini abdomenultraccâmpuri t fără a le implementa.

Exemplu:

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

Aceste câmpuri sunt implementate de clasele care extind trăsătura sau abs-ultracclasa t. Poți folosi trăsături pentru a crea contracts pentru ce ar trebui să facă o aplicație și apoi să implementeze acele metode mai târziu.

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

În acest fel, puteți planifica cum va arăta o aplicație fără a implementa metodele, ajutăping vă imaginați cum vor apărea diverse metode. Se urmează un model cunoscut sub numele de programare pentru abdomentracțiuni, mai degrabă decât la implementarea propriu-zisă.

O clasă a început cu abstract cuvântul cheie poate conține ambele abdomenetract și non-abstracmetode t. Cu toate acestea, moștenirea multiplă nu este acceptată în abstracclase t, astfel încât să poți extinde doar un abdomentracclasa t.

Obiecte Singleton

Un singleton este o clasă instanțiată o singură dată într-un program. Provine dintr-un model de programare popular și util, cunoscut sub numele de „model singleton”. Este util pentru crearea de instanțe menite să fie de lungă durată și accesate frecvent în cadrul programului, unde starea este parte integrantă a coordonării evenimentelor dintr-un sistem. Crearea unei astfel de clase în Scala este ușoară deoarece Scala oferă o modalitate simplă de a crea singletoni folosind object cuvinte cheie.

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

Apoi puteți face referire la acest obiect în tot programul, cu garanția că toate părțile programului văd aceleași date, deoarece există o singură instanță a acestuia.

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

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

Conceptul de membri statici nu există în Scala, motiv pentru care se utilizează obiecte singleton care se comportă ca membri statici ai unei clase.

Clasele implicite

Clasele implicite sunt o funcționalitate adăugată în versiunea 2.10 și sunt utilizate în principal pentru a adăuga noi funcționalități claselor închise existente.

implicit Cuvântul cheie ar trebui definit într-o clasă, un obiect sau o trăsătură. Constructorul principal al unei clase implicite trebuie să aibă exact un argument în prima listă de parametri. Poate include și o listă suplimentară de parametri impliciti.

În exemplul Scala de mai jos, este adăugată o nouă funcționalitate pentru înlocuirea vocalelor unui șir de caractere cu *.

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

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

Trebuie să importați clasa implicită în clasa în care o utilizați.

import StringUtil.StringEnhancer

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

Programare orientată pe obiecte (POO) vs. Programare funcțională (FP)

În POO, programele sunt construite de grupuriping datele și funcțiile care operează asupra acestor date în unități extrem de conectate. Obiectele își transportă datele în câmpuri, iar metodele operează asupra lor. În acest stil de programare, principalele abstracțiunea reprezintă datele, deoarece metodele create sunt menite să opereze asupra datelor.

Programare funcțională, pe de altă parte, separă datele și funcțiile care operează asupra lor. Acest lucru permite dezvoltatorilor să trateze funcțiile ca fiind absoarbetracțiune și forță motrice la modelarea programelor.

Scala permite programarea funcțională tratând funcțiile ca fiind cetățeni de primă clasă, permițându-le să fie transmise ca valori către alte funcții și returnate tot ca valori. Combinarea acestor două paradigme a făcut din Scala o alegere excelentă pentru construirea de software complex în industrii precum știința datelor.

Cadre importante pe Scala

Iată câteva framework-uri importante pentru Scala:

  • Joaca este un cadru de aplicații web open-source care utilizează Arhitectura MVCLansat în 2007 și acum licențiat sub Apache, a devenit unul dintre cele mai populare framework-uri de pe GitHub până în 2013. Companii precum LinkedIn, Walmart, Samsung și Eero folosesc acest framework.
  • Ridicare este un alt framework web gratuit scris în Scala, lansat în 2007. Foursquare folosește framework-ul Lift. Este un framework de înaltă performanță, cu care se poate construi rapid.
  • Acru oferă un set de instrumente pentru construirea de aplicații bazate pe mesaje, cu un nivel ridicat de concurență, distribuite și reziliente, pe JVM.
  • Pisici este o bibliotecă care oferă informații despre abstracțiuni pentru programare funcțională.
  • Spark este un motor de analiză unificat pentru procesarea datelor la scară largă, utilizat pe scară largă în fluxurile de lucru de tip big data și machine learning.

Suport simultan

  • Valorile din Scala sunt imuabile în mod implicit, ceea ce îl face foarte adaptabil la medii concurente.
  • Scala are multe caracteristici care îl fac ideal pentru aplicații concurente.
  • Futures and Promises facilitează procesarea asincronă a datelor, susținând astfel paralelismul.
  • Akka este un set de instrumente care folosește modelul de concurență a actorilor. Actorii acționează atunci când primesc mesaje.
  • Concurență folosind fire din Java este, de asemenea, suportat în Scala.
  • Procesarea fluxurilor este o altă caracteristică excelentă care permite procesarea continuă, în timp real, a datelor.

Scala are unele dintre cele mai bune biblioteci de concurență din Java ecosistem:

  • Nativ Java fire.
  • Fibre din biblioteci precum Vertx.
  • ZIO, o bibliotecă ce conține primitive pentru a ajuta la gestionarea concurenței și a calculului asincron.
  • Memorie tranzacțională software (STM) pentru tranzacții.
  • Future, care este încorporat în limbajul Scala.

Java vs Scala

Iată care sunt principalele diferente intre Java și Scala.

Scala Java
Mai compact și mai concis. Bucăți de cod relativ mai mari.
Conceput și dezvoltat atât pentru a fi orientat pe obiecte, cât și funcțional. Acceptă o gamă largă de caracteristici de programare funcțională, cum ar fi concurența și imutabilitatea. Inițial dezvoltat ca un limbaj orientat pe obiecte, a început să ofere suport pentru funcții de programare funcțională în versiunile recente. Încă nu este la fel de puternic ca Scala pentru programarea funcțională.
Folosește modelul actorului pentru susținerea concurenței. Utilizează modelul convențional bazat pe fire pentru concurență.
Acceptă framework-uri precum Play și Lift. Suportă Spring, Grails și multe altele.
Suportă evaluarea leneșă. Nu suportă nativ evaluarea leneșă.
Fără membri statici. Conține membri statici.
Suportă supraîncărcarea operatorilor. Nu suportă supraîncărcarea operatorilor.
Compilarea codului sursă este relativ lentă. Compilarea codului sursă este mai rapidă decât în ​​Scala.
Trăsăturile se comportă ca Java 8 interfețe. Java 8 interfețe încearcă să elimine decalajul dintre clase și interfețe.
Rescrierea este uneori necesară la actualizarea versiunilor. Rescrierea nu este, în general, necesară între versiuni.
Siguranța tipurilor oferă o fiabilitate puternică a codului, dar nu garantează absolut lipsa erorilor. electricitate statică puternicăping ajută la reducerea multor defecte de execuție.
Are unele limite de compatibilitate inversă între versiunile majore. Compatibilitate retroactivă puternică pe termen lung.
OperaTorii sunt tratați ca apeluri de metodă. Operatorii au o sintaxă specială și nu sunt apeluri de metodă.
Suportă moștenirea multiplă folosind trăsături. Nu suportă moștenirea multiplă folosind clase; folosește în schimb interfețe.
Code este scrisă într-o formă compactă. Code este scrisă într-o formă mai detaliată.
Scala nu conține cuvântul cheie static. Java conține cuvântul cheie static.

Întrebări frecvente

Scala are o curbă de învățare mai abruptă decât Java deoarece îmbină stilurile orientate pe obiecte și funcționale. Cu toate acestea, dezvoltatorii cu Java Cei cu experiență, de obicei, învață rapid elementele de bază. Exersează cu proiecte mici și Scala REPL accelerează învățarea.

Da. Scala continuă să alimenteze sisteme la scară largă în companii care utilizează Akka. Sparkși Kafka. Cererea rămâne puternică în ingineria datelor, fintech și sistemele distribuite, unde performanța JVM și programarea funcțională sunt valoroase.

Da. Asistenții moderni de codare bazați pe inteligență artificială înțeleg sintaxa Scala, sistemul de tipuri și framework-uri precum Akka și SparkAcestea ajută la generarea de șabloane standard, sugerează modele funcționale, explică erorile de compilare și refactorizează codul, accelerând dezvoltarea atât pentru începători, cât și pentru experți.

Scala controlează Apache Spark, principalul motor pentru procesarea datelor la scară largă în conductele de inteligență artificială. Biblioteci precum Breeze, Smile și Figaro acceptă calcul numeric, învățare automată și modelare probabilistică, ceea ce face din Scala o alegere puternică pentru știința datelor de producție.

O valoare val creează o legătură imuabilă evaluată imediat. O valoare var creează o legătură mutabilă care poate fi reatribuită. O valoare lazy amână evaluarea până când valoarea este accesată pentru prima dată, apoi stochează rezultatul în cache pentru citiri ulterioare.

Rezumați această postare cu: