Poradnik Scali

โšก Inteligentne podsumowanie

Scala Tutorial wprowadza statycznie typowany jฤ™zyk oparty na JVM, ktรณry ล‚ฤ…czy programowanie obiektowe i funkcyjne. Przewodnik obejmuje instalacjฤ™, skล‚adniฤ™, podstawowe funkcje i frameworki, ktรณre sprawiajฤ…, ลผe Scala idealnie nadaje siฤ™ do tworzenia wspรณล‚bieลผnych, skalowalnych i zwiฤ™zล‚ych, nowoczesnych aplikacji.

  • ๐Ÿ”˜ Paradigmat hybrydowy: Scala ล‚ฤ…czy programowanie obiektowe i funkcjonalne na maszynie wirtualnej Java (JVM), umoลผliwiajฤ…c programistom poล‚ฤ…czenie niezmiennoล›ci, funkcji pierwszorzฤ™dnych i tradycyjnych hierarchii klas.
  • ๏ธ Zwiฤ™zล‚a skล‚adnia: Wnioskowanie typu, funkcje anonimowe i dopasowywanie wzorcรณw redukujฤ… liczbฤ™ szablonรณw w porรณwnaniu z Java podczas gdy keeping kod jest wyrazisty i czytelny.
  • โœ… Konfiguracja za pomocฤ… IntelliJ: Zainstaluj ล›rodowisko IDE Community Edition, dodaj wtyczkฤ™ Scala i utwรณrz obiekt rozszerzajฤ…cy aplikacjฤ™, aby uruchomiฤ‡ pierwszy program Hello World.
  • ๐Ÿงช Bloki funkcjonalne: Leniwa ocena, curry, funkcje wyลผszego rzฤ™du i niezmiennoล›ฤ‡ poprzez val wspomagajฤ… czysty i przewidywalny kod.
  • ๐Ÿ› ๏ธ. Wspรณล‚bieลผnoล›ฤ‡ i struktury: Aktorzy Akka, Futures, Play, Lift i Spark sprawiajฤ…, ลผe Scala jest doskonaล‚ym wyborem dla systemรณw rozproszonych, aplikacji internetowych i inลผynierii danych.

Poradnik Scali

Czym jest Scala?

Scala to statycznie typowany jฤ™zyk programowania, ktรณry ล‚ฤ…czy programowanie obiektowe i funkcyjne w celu poprawy skalowalnoล›ci aplikacji. Scala dziaล‚a gล‚รณwnie na platformie JVM, a programiล›ci mogฤ… jej rรณwnieลผ uลผywaฤ‡ do pisania oprogramowania na platformy natywne za poล›rednictwem Scala-Native lub na przeglฤ…darki za poล›rednictwem ScalaJS iโ€ฆ JAVASCRIPT czas wykonywania.

Scala to skalowalny jฤ™zyk uลผywany do tworzenia oprogramowania na wiele platform, od ktรณrego wziฤ™ล‚a siฤ™ jego nazwa. Jฤ™zyk ten zostaล‚ zaprojektowany, aby rozwiฤ…zaฤ‡ kilka problemรณw zwiฤ…zanych z โ€žrozwlekล‚oล›ciฤ…โ€ wโ€ฆ Java zachowujฤ…c jednoczeล›nie zwiฤ™zล‚oล›ฤ‡. Martin Odersky zaprojektowaล‚ Scalฤ™, a jej pierwsza publiczna wersja ukazaล‚a siฤ™ w 2004 roku.

Dlaczego warto uczyฤ‡ siฤ™ Scali

Oto najwaลผniejsze powody, dla ktรณrych warto nauczyฤ‡ siฤ™ jฤ™zyka programowania Scala:

  • Scala jest ล‚atwa do nauczenia dla programistรณw obiektowych i Java programistรณw i staล‚ siฤ™ jednym z popularnych jฤ™zykรณw w ostatnich latach.
  • Scala oferuje uลผytkownikom najwyลผszej klasy funkcje.
  • Scalฤ™ moลผna wykonaฤ‡ na FMV, torujฤ…c drogฤ™ do interoperacyjnoล›ci z innymi jฤ™zykami.
  • Jest on przeznaczony do aplikacji wspรณล‚bieลผnych, rozproszonych i odpornych na bล‚ฤ™dy, sterowanych komunikatami, co czyni go jednym z najbardziej poลผฤ…danych jฤ™zykรณw tej dekady.
  • Jest to zwiฤ™zล‚y i potฤ™ลผny jฤ™zyk, ktรณry moลผe szybko rozwijaฤ‡ siฤ™ w zaleลผnoล›ci od potrzeb uลผytkownikรณw.
  • Jest zorientowany obiektowo i zawiera wiele funkcji programowania funkcyjnego, dajฤ…c programistom duลผฤ… swobodฤ™ w pisaniu kodu.
  • Scala oferuje Duck Typing poprzez typy strukturalne.
  • Zawiera mniej szablonรณw niลผ Java.
  • Frameworki Lift i Play, napisane w jฤ™zyku Scala, stale siฤ™ rozwijajฤ… i zyskujฤ… na popularnoล›ci.

Jak zainstalowaฤ‡ Scalฤ™

Aby rozpoczฤ…ฤ‡ pisanie programรณw w Scali, musisz jฤ… zainstalowaฤ‡ na swoim komputerze. Aby to zrobiฤ‡, odwiedลบ oficjalnฤ… stronฤ™: https://www.scala-lang.org/download/ aby pobraฤ‡ najnowszฤ… wersjฤ™ jฤ™zyka Scala.

Po klikniฤ™ciu linku zobaczysz dwie opcje instalacji Scali. W tym samouczku Scali uลผyjemy IntelliJ IDEA, ktรณry od razu po zainstalowaniu zapewnia doskonaล‚e wsparcie jฤ™zyka Scala.

Jak zainstalowaฤ‡ Scalฤ™

Po klikniฤ™ciu ล‚ฤ…cza pobierania znajdziesz dwie edycje ล›rodowiska IDE IntelliJ.

Na potrzeby tego samouczka dotyczฤ…cego jฤ™zyka Scala pobierzemy wersjฤ™ Community Edition, ktรณra jest bezpล‚atna i zawiera wszystko, czego potrzebujesz do pisania programรณw w jฤ™zyku Scala.

Strona pobierania IntelliJ Community Edition

Krok 1) Wybierz wersjฤ™ Community Edition.
Na stronie kliknij menu rozwijane Community Edition.

Zawiera opcjฤ™ pobrania ล›rodowiska IntelliJ IDE wraz z JBR, ktรณre zawiera implementacjฤ™ JDK (Java Zestaw narzฤ™dzi programistycznych (Development Kit), taki jak OpenJDK, ktรณrego jฤ™zyk Scala potrzebuje do kompilowania i uruchamiania kodu.

Pobierz IntelliJ z JBR

Krok 2) Uruchom instalacjฤ™.
Po pobraniu IntelliJ kliknij dwukrotnie instalator i postฤ™puj zgodnie z instrukcjami kreatora wyล›wietlanymi na ekranie.

Kreator instalacji IntelliJ

Krok 3) Wybierz lokalizacjฤ™.
Wybierz lokalizacjฤ™, w ktรณrej chcesz zainstalowaฤ‡ IDE.

Wybierz folder instalacyjny

Jeล›li nie pobrano pakietu z JDK, instalator i tak poprosi o dodanie JDK za pomocฤ… pola wyboru podczas konfiguracji.

Pole wyboru JDK podczas instalacji

Krok 4) Kliknij Nastฤ™pny.
Pozostaล‚e ustawienia domyล›lne pozostaw bez zmian i kliknij Dalej.

Domyล›lne opcje instalatora

Program Scala Hello World

Krok 5) Kliknij ikonฤ™ uruchamiania.
Po zakoล„czeniu instalacji uruchom ล›rodowisko IntelliJ IDE, klikajฤ…c jego ikonฤ™ startowฤ… w menu Start, tak jak zwykล‚ฤ… aplikacjฤ™.

Ekran powitalny IntelliJ

Nadal musisz dodaฤ‡ wtyczkฤ™ Scala do IntelliJ. Kliknij menu rozwijane w menu konfiguracji w prawym dolnym rogu ekranu i wybierz opcjฤ™ โ€žWtyczkiโ€.

Konfiguruj menu dla wtyczek

Rynek wtyczek IntelliJ

Na karcie Marketplace wyszukaj Scala. Wtyczka pojawi siฤ™ jako pierwszy wynik pod etykietฤ… Jฤ™zyki.

Krok 6) Zainstaluj wtyczkฤ™.
Kliknij Zainstaluj, aby rozpoczฤ…ฤ‡ pobieranie wtyczki Scala.

Zainstaluj wtyczkฤ™ Scala

Krok 7) Uruchom ponownie ล›rodowisko IDE.
Po zakoล„czeniu pobierania zostaniesz poproszony o ponowne uruchomienie IDE, aby zainstalowana wtyczka mogล‚a zaczฤ…ฤ‡ dziaล‚aฤ‡.

Uruchom ponownie wiersz poleceล„ IntelliJ

Po ponownym uruchomieniu wrรณcisz do tej samej strony, ale tym razem wtyczka Scala bฤ™dzie zainstalowana i gotowa.

Krok 8) Wybierz opcjฤ™ Utwรณrz projekt, ktรณra przeniesie Ciฤ™ na stronฤ™, na ktรณrej moลผesz wybraฤ‡ jฤ™zyk projektu.

Utwรณrz nowy projekt w IntelliJ

Krok 9) Wybierz Scalฤ™, zaznaczajฤ…c pole wyboru Scala i klikajฤ…c Dalej.

Wybierz jฤ™zyk Scala

Krok 10) Wybierz lokalizacjฤ™, w ktรณrej chcesz zapisaฤ‡ plik projektu i nadaj mu nazwฤ™.

Nazwij i zlokalizuj projekt

Jeล›li katalog nie istnieje, IntelliJ poprosi o pozwolenie na utworzenie folderu. Zaakceptuj i kliknij Zakoล„cz. Nastฤ™pnie zostaniesz przeniesiony do swojego projektu Scala, ktรณry obecnie nie zawiera ลผadnego kodu Scala.

ลadowanie indeksรณw zajmuje trochฤ™ czasu, wiฤ™c nie martw siฤ™, jeล›li nie moลผesz korzystaฤ‡ ze ล›rodowiska IDE, gdy na dole wyล›wietla siฤ™ pasek postฤ™pu. IDE ล‚aduje pliki wymagane do uruchomienia jฤ™zyka Scala i zapewnia funkcjฤ™ autouzupeล‚niania.

Krok 11) Kliknij kartฤ™ Projekt po lewej stronie ล›rodowiska IDE i rozwiล„ jฤ…, aby zobaczyฤ‡ zawartoล›ฤ‡ projektu.

Rozwiล„ kartฤ™ projektu

Na tym etapie projekt jest pusty i zawiera jedynie folder .idea oraz plik hello-world.iml wygenerowany przez IDE. Interesujฤ…cy jest folder src, w ktรณrym znajduje siฤ™ kod ลบrรณdล‚owy projektu. To wล‚aล›nie tam tworzysz swรณj pierwszy plik Scala.

Krok 12) Kliknij prawym przyciskiem myszy na src, aby otworzyฤ‡ menu i utworzyฤ‡ nowy plik Scala.

Utwรณrz nowy plik Scala

Wybierz nazwฤ™ pliku. W tym samouczku dotyczฤ…cym jฤ™zyka Scala uลผyj czeล›ฤ‡, a nastฤ™pnie wybierz Obiekt z listy rozwijanej, aby okreล›liฤ‡ typ zawartoล›ci pliku Scala.

Wybierz rodzaj obiektu

Po wykonaniu tej czynnoล›ci otrzymasz plik Scala zawierajฤ…cy obiekt singleton, ktรณrego bฤ™dziesz uลผywaฤ‡ do uruchamiania kodu.

Utworzono obiekt singleton

Majฤ…c juลผ plik Scala zawierajฤ…cy obiekt Hello, moลผesz napisaฤ‡ swรณj pierwszy program, rozszerzajฤ…c obiekt utworzony za pomocฤ… sล‚owa kluczowego App.

Rozszerzenie obiektu o App informuje kompilator, ktรณry kod ma zostaฤ‡ uruchomiony podczas startu programu. Zaraz po rozszerzeniu App po lewej stronie pojawia siฤ™ zielona strzaล‚ka, wskazujฤ…ca, ลผe โ€‹โ€‹program jest teraz gotowy do uruchomienia.

Uruchom strzaล‚kฤ™ w IntelliJ

Uruchom opcjฤ™ Hello

W obiekcie Hello wpisz funkcjฤ™ println(), aby wydrukowaฤ‡ tekst na konsoli. Uruchom program, klikajฤ…c zielonฤ… strzaล‚kฤ™.

Klikniฤ™cie strzaล‚ki wyล›wietla opcjฤ™ โ€žUruchom Helloโ€. Wybranie jej powoduje kompilacjฤ™ kodu, a po kilku sekundach w konsoli IntelliJ pojawi siฤ™ wynik dziaล‚ania programu.

Wyjล›cie Hello World w konsoli

Pomyล›lnie zainstalowaล‚eล› Scalฤ™ i uruchomiล‚eล› swรณj pierwszy program.

Co moลผesz zrobiฤ‡ ze Scalฤ…

Scala jest szeroko stosowana w wielu dziedzinach ze wzglฤ™du na swojฤ… elastycznoล›ฤ‡ i interoperacyjnoล›ฤ‡ z JVM. Typowe zastosowania obejmujฤ…:

  • Tworzenie front-endu stron internetowych w ScalaJS.
  • Rozwรณj mobilny dla Android i iOS z natywnฤ… obsล‚ugฤ… Scala.
  • Biblioteki po stronie serwera, takie jak HTTP4S, Akka-Http i Play Framework.
  • Zastosowania Internetu Rzeczy (IoT).
  • Produkcja gier.
  • Przetwarzanie jฤ™zyka naturalnego z wykorzystaniem pakietu bibliotek ScalaNLP.
  • Wspรณlne ฤ‡wiczenie zaawansowanych technik, takich jak programowanie funkcyjne i programowanie obiektowe.
  • Wysoce wspรณล‚bieลผne aplikacje komunikacyjne wykorzystujฤ…ce aktorรณw, bibliotekฤ™ dla JVM inspirowanฤ… Erlangiem.
  • Uczenie maszynowe z bibliotekami takimi jak Figaro do programowania probabilistycznego i Apache Spark do przetwarzania danych na duลผฤ… skalฤ™.

Funkcje anonimowe

Jฤ™zyk Scala obsล‚uguje funkcje anonimowe, zwane takลผe literaล‚y funkcyjnePoniewaลผ Scala jest jฤ™zykiem funkcyjnym, programiล›ci czฤ™sto dzielฤ… duลผe problemy na wiele maล‚ych zadaล„ i tworzฤ… wiele funkcji. Aby to uล‚atwiฤ‡, Scala pozwala na tworzenie funkcji utworzone bez nazwyMoลผesz je przypisaฤ‡ bezpoล›rednio do zmiennych lub definicji za pomocฤ… def, jak pokazano w poniลผszym przykล‚adzie Scala:

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

Nastฤ™pnie moลผna ich uลผywaฤ‡ jak zwykล‚ych funkcji, przekazujฤ…c parametry:

multiplyByTwo(3)
//6

multiplyByThree(4)
//12

Te metody sฤ… przydatne, gdy zaleลผy Ci na przejrzystym i zwiฤ™zล‚ym kodzie. Funkcje anonimowe sฤ… przydatne przy definiowaniu metod, ktรณre sฤ… maล‚e i nie wymagajฤ… duลผej iloล›ci kodu w swoim ciele. Sฤ… bardzo proste i nie wymagajฤ… ลผadnych formalnoล›ci przy tworzeniu.

Metody te nie ograniczajฤ… siฤ™ wyล‚ฤ…cznie do funkcji z argumentami i moลผna ich uลผywaฤ‡ do tworzenia instancji metod, ktรณre nie przyjmujฤ… ลผadnych argumentรณw.

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

Wiฤ™kszoล›ฤ‡ tych anonimowych funkcji jest uลผywana w innych czฤ™ล›ciach kodu, w ktรณrych potrzebna jest szybka funkcja. Z tego powodu nazywa siฤ™ je rรณwnieลผ funkcje wbudowaneKorzystanie z funkcji anonimowych to powszechny wzorzec pojawiajฤ…cy siฤ™ w caล‚ej bibliotece kolekcji w celu wykonywania szybkich akcji na kolekcji.

Na przykล‚ad metoda filter przyjmuje funkcjฤ™ inline w celu utworzenia innej kolekcji zawierajฤ…cej wyล‚ฤ…cznie elementy speล‚niajฤ…ce kryteria zdefiniowane w funkcji anonimowej.

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)

W tym przypadku funkcje anonimowe sprawdzajฤ…, czy wartoล›ฤ‡ na liล›cie jest parzysta czy nieparzysta i zwracajฤ… pasujฤ…cy element.

//the one checking that the value is even
(n: Int) => n % 2 == 0

//the one checking that the value is odd
(n:Int) => n % 2 != 0

W Scali moลผliwe jest rรณwnieลผ uลผycie symboli wieloznacznych, gdy parametr funkcji anonimowej nie jest nazwany. Na przykล‚ad:

var timesTwo = (_:Int) * 2

timesTwo(5)
//10

W tym scenariuszu nie nadajesz parametrowi nazwy. Do jego reprezentacji uลผywa siฤ™ znaku podkreล›lenia.

Leniwa ocena

Wiฤ™kszoล›ฤ‡ jฤ™zykรณw ocenia zmienne i parametry funkcji sekwencyjnie, jeden po drugim. W Scali sล‚owo kluczowe lazy pomaga radziฤ‡ sobie z wartoล›ciami, ktรณrych nie chcesz oceniaฤ‡, dopรณki siฤ™ do nich nie odwoล‚asz.

Zmienna oznaczona jako leniwa nie jest oceniana w miejscu, w ktรณrym zostaล‚a zdefiniowana, co jest powszechnie znane jako ocena zachล‚anna. Jest ona oceniana dopiero po odwoล‚aniu siฤ™ do niej w dalszej czฤ™ล›ci kodu.

Moลผe to byฤ‡ pomocne, gdy ocena wartoล›ci byล‚aby kosztownym obliczeniem. Jeล›li wartoล›ฤ‡ nie jest zawsze potrzebna, oszczฤ™dzasz sobie wykonywania kosztownych obliczeล„, ktรณre mogล‚yby spowolniฤ‡ dziaล‚anie oprogramowania, powodujฤ…c, ลผe zmienna staล‚aby siฤ™ leniwa.

lazy val myExpensiveValue = expensiveComputation

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

To nie jedyny przypadek zastosowania zmiennych โ€žleniwychโ€. Pomagajฤ… one rรณwnieลผ radziฤ‡ sobie z zaleลผnoล›ciami cyklicznymi w kodzie.

Jeล›li flaga ustawieล„ ma wartoล›ฤ‡ false, nie musisz uลผywaฤ‡ myExpensiveValue, co pozwala uniknฤ…ฤ‡ kosztownych obliczeล„. Pomaga to zapewniฤ‡ uลผytkownikom pล‚ynne dziaล‚anie, poniewaลผ zasoby nie sฤ… marnowane na wartoล›ci, ktรณre nigdy nie sฤ… odczytywane.

Lenistwo pomaga rรณwnieลผ w przypadku argumentรณw funkcji, gdzie argumenty sฤ… uลผywane tylko wtedy, gdy odwoล‚ujemy siฤ™ do nich wewnฤ…trz funkcji. Ta koncepcja nazywa siฤ™ parametrami wywoล‚ania przez nazwฤ™.

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

Wiele jฤ™zykรณw programowania wykorzystuje podejล›cie call-by-value do oceny argumentรณw. Parametr przekazywany przez call-by-name jest oceniany tylko wtedy, gdy jest potrzebny w ciele funkcji. Po ocenie wartoล›ฤ‡ jest zapisywana i moลผe byฤ‡ ponownie uลผyta bez koniecznoล›ci ponownej oceny โ€“ koncepcja ta nazywa siฤ™ memoizacjฤ….

Wpisz wnioskowanie

W Scali nie trzeba deklarowaฤ‡ typรณw dla kaลผdej tworzonej zmiennej, poniewaลผ kompilator Scali moลผe wnioskowaฤ‡ typy z prawej strony wyraลผenia. Dziฤ™ki temu kod jest bardziej zwiฤ™zล‚y i nie trzeba pisaฤ‡ szablonowych kodรณw, w ktรณrych oczekiwany typ jest oczywisty.

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

Funkcja wyลผszego rzฤ™du

Funkcja wyลผszego rzฤ™du to funkcja, ktรณra moลผe przyjmowaฤ‡ funkcje jako argumenty i zwracaฤ‡ funkcjฤ™ jako typ zwracany. W Scali funkcje sฤ… traktowane jako obywatele pierwszej klasy. Korzystanie z funkcji w ten sposรณb zapewnia duลผฤ… elastycznoล›ฤ‡ w zakresie rodzajรณw tworzonych programรณw. Moลผna tworzyฤ‡ funkcje dynamicznie i dynamicznie przekazywaฤ‡ funkcjonalnoล›ฤ‡ innym funkcjom.

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

W powyลผszej funkcji przekazujesz Int i funkcja, ktรณra przyjmuje Int i zwraca IntMoลผesz przekazaฤ‡ dowolnฤ… funkcjฤ™ o tej sygnaturze. Przez sygnaturฤ™ rozumiemy dane wejล›ciowe i wyjล›ciowe funkcji. Sygnatura Int => Int oznacza, ลผe โ€‹โ€‹funkcja przyjmuje wartoล›ฤ‡ Int jako dane wejล›ciowe i zwraca wartoล›ฤ‡ Int jako dane wyjล›ciowe.

Podpis () => Int Oznacza to, ลผe funkcja przyjmuje nic jako dane wejล›ciowe i zwraca wartoล›ฤ‡ typu Int jako wynik. Przykล‚adem takiej funkcji jest funkcja generujฤ…ca losowฤ… wartoล›ฤ‡ typu int.

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

Powyลผsza funkcja ma sygnaturฤ™ () => Int.

Funkcja moลผe rรณwnieลผ mieฤ‡ sygnaturฤ™ () => UnitOznacza to, ลผe funkcja nie przyjmuje ลผadnych danych i nie zwraca typu. Zamiast tego moลผe zmieniฤ‡ jakiล› stan lub wykonaฤ‡ z gรณry okreล›lonฤ… akcjฤ™.

Tego typu metody nie sฤ… zalecane, poniewaลผ mogฤ… dziaล‚aฤ‡ jak czarna skrzynka, wpล‚ywajฤ…c na system w nieznany sposรณb. Sฤ… one rรณwnieลผ trudniejsze do przetestowania. Jawne okreล›lenie typรณw danych wejล›ciowych i wyjล›ciowych pozwala na wnioskowanie o dziaล‚aniu funkcji.

Funkcja wyลผszego rzฤ™du moลผe rรณwnieลผ zwracaฤ‡ funkcjฤ™. Na przykล‚ad, moลผesz utworzyฤ‡ metodฤ™ zwracajฤ…cฤ… funkcjฤ™ potฤ™gujฤ…cฤ…, czyli takฤ…, ktรณra przyjmuje liczbฤ™ i stosuje do niej potฤ™gฤ™.

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

Powyลผsza funkcja przyjmuje wartoล›ฤ‡ typu Int. Jej typem zwracanym jest funkcja anonimowa przyjmujฤ…ca wartoล›ฤ‡ typu Int. x i uลผywa go jako argumentu dla funkcji potฤ™gowej.

Curry

W Scali moลผna przeksztaล‚ciฤ‡ funkcjฤ™ przyjmujฤ…cฤ… dwa argumenty w funkcjฤ™ przyjmujฤ…cฤ… po jednym argumencie. Przekazujฤ…c jeden argument, czฤ™ล›ciowo go stosujesz, a na koล„cu otrzymujesz funkcjฤ™ przyjmujฤ…cฤ… pozostaล‚y argument, aby zakoล„czyฤ‡ wywoล‚anie. Currying pozwala na tworzenie funkcji poprzez czฤ™ล›ciowe dodawanie argumentรณw.

Jest to przydatne w przypadku dynamicznego tworzenia funkcji, zanim uzyskasz kompletny zestaw argumentรณw.

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

Jeล›li potrzebujesz funkcji mnoลผฤ…cej przez okreล›lonฤ… liczbฤ™, nie musisz tworzyฤ‡ kolejnej metody mnoลผenia. Moลผesz zastosowaฤ‡ jeden argument do funkcji curry i ponownie wykorzystaฤ‡ wynik:

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

var multiplyByFive = multiplyTwoNumbers(5) _

multiplyByFive(4)

//returns 20

Dopasowywanie wzorcรณw

Jฤ™zyk Scala ma wbudowany, potฤ™ลผny mechanizm, ktรณry pomaga sprawdziฤ‡, czy zmienna speล‚nia okreล›lone kryteria, podobnie jak instrukcja switch w Java lub ล‚aล„cuch instrukcji if/else. Jฤ™zyk obsล‚uguje dopasowywanie wzorcรณw, ktรณrego moลผna uลผyฤ‡ do sprawdzenia, czy zmienna jest okreล›lonego typu. Dopasowywanie wzorcรณw w Scali jest potฤ™ลผne i umoลผliwia destrukturyzacjฤ™ komponentรณw, ktรณre majฤ… unapply metoda umoลผliwiajฤ…ca pobranie interesujฤ…cych Ciฤ™ pรณl bezpoล›rednio ze zmiennej podlegajฤ…cej dopasowaniu.

Dopasowywanie wzorcรณw w jฤ™zyku Scala charakteryzuje siฤ™ rรณwnieลผ przyjemniejszฤ… skล‚adniฤ… niลผ polecenie switch.

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

Porรณwnujesz zmiennฤ… z zestawem opcji. Gdy zmienna speล‚nia kryteria, wyraลผenie po prawej stronie grubej strzaล‚ki (=>) jest oceniane i zwracane jako wynik dopasowania.

Podkreล›lenie wychwytuje przypadki, ktรณre nie zostaล‚y uwzglฤ™dnione w kodzie, odzwierciedlajฤ…c zachowanie przypadku domyล›lnego w instrukcji 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
}

W powyลผszym kodzie moลผna wykryฤ‡ typ myItem zmiennฤ… i na jej podstawie przejล›ฤ‡ do konkretnego kodu.

Dopasowywanie wzorcรณw sprawdza, czy zmienna pasuje do kaลผdego przypadku w kolejnoล›ci.

Podkreล›lenie dziaล‚a jako symbol zastฤ™pczy, ktรณry pasuje do kaลผdego warunku, ktรณrego nie pasujฤ… inne instrukcje case. Bierzesz zmiennฤ… myItem i zadzwoล„ do match Metoda.

  • Sprawdลบ pogodฤ™ myItem is true i uruchom logikฤ™ po prawej stronie grubej strzaล‚ki โ€ž=>โ€.
  • Uลผyj podkreล›lenia, aby dopasowaฤ‡ wszystko, co nie pasuje do ลผadnego ze stwierdzeล„ case zdefiniowanych w kodzie.

Za pomocฤ… klas przypadkรณw moลผna rozล‚oลผyฤ‡ klasฤ™ na np.tracpola t wewnฤ…trz obiektu.

Przy uลผyciu sealed sล‚owo kluczowe definiujฤ…ce klasy, dziฤ™ki ktรณremu kompilator dokล‚adnie sprawdza przypadki, ktรณre prรณbujesz dopasowaฤ‡, i ostrzega Ciฤ™, jeล›li zapomnisz o obsล‚uลผeniu ktรณregoล› z nich.

Niezmiennoล›ฤ‡

Moลผna tworzyฤ‡ wartoล›ci, ktรณrych nie moลผna zmieniฤ‡ za pomocฤ… innych funkcji w Scali, uลผywajฤ…c val sล‚owo kluczowe. Osiฤ…ga siฤ™ to w Java przy uลผyciu final sล‚owo kluczowe. W Scali uลผywasz val podczas tworzenia zmiennej zamiast var, ktรณra jest alternatywฤ… dla zmiennych zmiennych.

Zmienna zdefiniowana za pomocฤ… val Sล‚owo kluczowe jest tylko do odczytu, podczas gdy zdefiniowane za pomocฤ… var mogฤ… byฤ‡ odczytane i zmienione pรณลบniej przez inne funkcje lub przez uลผytkownika w kodzie.

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

Prรณba przypisania wartoล›ci myNumber po ogล‚oszeniu tego jako val zgล‚asza bล‚ฤ…d kompilacji: โ€žreassignment to val.โ€

Po co uลผywaฤ‡ niezmiennoล›ci?

Niezmiennoล›ฤ‡ pomaga zapobiegaฤ‡ nieoczekiwanym zmianom wartoล›ci przez kod i innych programistรณw, co prowadziล‚oby do nieprzewidywalnych rezultatรณw. Jeล›li odbiorcy wartoล›ci muszฤ… jฤ… zmieniฤ‡, mogฤ… jฤ… skopiowaฤ‡. W ten sposรณb zapobiega siฤ™ bล‚ฤ™dom spowodowanym przez wielu aktorรณw zmieniajฤ…cych tฤ™ samฤ… zmiennฤ….

Klasy i przedmioty

Obiekty to byty ze ล›wiata rzeczywistego, a klasa to szablon definiujฤ…cy obiekty. Klasy majฤ… zarรณwno stan, jak i zachowania. Stany to wartoล›ci lub zmienne. Zachowania to metody w Scali.

W nastฤ™pnej sekcji pokazano, jak zdefiniowaฤ‡ klasฤ™, utworzyฤ‡ jej instancjฤ™ i uลผywaฤ‡ jej w Scali.

Oto klasa o nazwie Rectangle, ktรณra ma dwie wartoล›ci i dwie funkcje. Moลผesz rรณwnieลผ uลผyฤ‡ parametrรณw l oraz b bezpoล›rednio jako pola w programie. Masz obiekt, ktรณry ma metodฤ™ gล‚รณwnฤ… i tworzy instancjฤ™ klasy z dwiema wartoล›ciami.

Przykล‚ad:

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

Wszystkie pola i metody sฤ… domyล›lnie publiczne w Scali. Korzystanie z nich jest niezbฤ™dne. override bo toString jest juลผ zdefiniowany dla kaลผdego obiektu w Scali.

Dziedzictwo

W jฤ™zyku Scala dostฤ™pne sฤ… rรณลผne typy dziedziczenia (pojedyncze, wielopoziomowe, wielokrotne, hierarchiczne i hybrydowe), ktรณre majฤ… wiele wspรณlnego z tradycyjnymi formami wystฤ™pujฤ…cymi w JavaMoลผesz dziedziczyฤ‡ zarรณwno po klasach, jak i cechach. Dziedziczysz elementy jednej klasy do innej klasy za pomocฤ… sล‚owa kluczowego extends. Dziฤ™ki temu moลผliwe jest ponowne wykorzystanie.

Moลผliwe jest dziedziczenie po jednej lub wielu klasach. Moลผliwe jest rรณwnieลผ dziedziczenie po podklasach, ktรณre same majฤ… swoje nadklasy, tworzฤ…c w ten sposรณb hierarchiฤ™ dziedziczenia.

W poniลผszym przykล‚adzie Scali klasฤ… bazowฤ… jest Circle, a klasa pochodna to SphereOkrฤ…g ma wartoล›ฤ‡ zwanฤ… promieniem, ktรณra jest dziedziczona w klasie Sphere. Metoda calcArea jest zastฤ™powany za pomocฤ… sล‚owa kluczowego override.

Przykล‚ad:

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

Abstraccja

W Scali moลผesz tworzyฤ‡ abstracmetody t i pola czล‚onkowskie wykorzystujฤ…ce abstracKlasy i cechy. Wewnฤ…trz brzuchatracklasy i cechy, moลผesz zdefiniowaฤ‡ abstracpola t bez ich implementacji.

Przykล‚ad:

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

Pola te sฤ… implementowane przez klasy rozszerzajฤ…ce cechฤ™ lub abstracKlasa t. Moลผesz uลผyฤ‡ cech, aby stworzyฤ‡tracokreล›lajฤ…, co aplikacja powinna robiฤ‡, a nastฤ™pnie implementujฤ… te metody pรณลบniej.

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

W ten sposรณb moลผesz zaplanowaฤ‡, jak bฤ™dzie wyglฤ…daล‚a aplikacja, bez koniecznoล›ci implementowania metod, helping Wyobraลผasz sobie, jak bฤ™dฤ… wyglฤ…daฤ‡ rรณลผne metody. Postฤ™puje to zgodnie ze schematem znanym jako programowanie abs.tracraczej na dziaล‚aniach niลผ na faktycznym wdroลผeniu.

Klasa poprzedzona abstract Sล‚owo kluczowe moลผe zawieraฤ‡ zarรณwno abstract i nie-abstracmetody t. Jednakลผe dziedziczenie wielokrotne nie jest obsล‚ugiwane w abstraczajฤ™cia, dziฤ™ki czemu moลผesz rozciฤ…gaฤ‡ tylko jeden miฤ™sieล„ brzuchatracklasa t.

Obiekty Singletona

Singleton to klasa, ktรณrej instancja jest tworzona tylko raz w programie. Wywodzi siฤ™ z popularnego i uลผytecznego wzorca programistycznego znanego jako โ€žwzorzec singletonโ€. Jest on przydatny do tworzenia instancji, ktรณre majฤ… byฤ‡ dล‚ugotrwaล‚e i powszechnie dostฤ™pne w caล‚ym programie, gdzie stan jest integralnฤ… czฤ™ล›ciฤ… koordynacji zdarzeล„ w systemie. Utworzenie takiej klasy w Scali jest ล‚atwe, poniewaลผ Scala oferuje prosty sposรณb tworzenia singletonรณw za pomocฤ… object sล‚owo kluczowe.

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

Nastฤ™pnie moลผna odwoล‚ywaฤ‡ siฤ™ do tego obiektu w caล‚ym programie, majฤ…c pewnoล›ฤ‡, ลผe wszystkie czฤ™ล›ci programu widzฤ… te same dane, poniewaลผ istnieje tylko jedno jego wystฤ…pienie.

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

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

W jฤ™zyku Scala nie istnieje koncepcja elementรณw statycznych, dlatego stosuje siฤ™ obiekty singleton, ktรณre zachowujฤ… siฤ™ jak elementy statyczne klasy.

Klasy niejawne

Klasy niejawne to funkcja dodana w wersji 2.10. Sล‚uลผฤ… gล‚รณwnie do dodawania nowej funkcjonalnoล›ci do istniejฤ…cych klas zamkniฤ™tych.

implicit Sล‚owo kluczowe powinno byฤ‡ zdefiniowane w klasie, obiekcie lub cesze. Gล‚รณwny konstruktor klasy niejawnej musi mieฤ‡ dokล‚adnie jeden argument na swojej pierwszej liล›cie parametrรณw. Moลผe rรณwnieลผ zawieraฤ‡ dodatkowฤ… niejawnฤ… listฤ™ parametrรณw.

W poniลผszym przykล‚adzie Scali dodano nowฤ… funkcjonalnoล›ฤ‡ umoลผliwiajฤ…cฤ… zastฤ™powanie samogล‚osek w ciฤ…gu znakรณw *.

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

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

Musisz zaimportowaฤ‡ klasฤ™ niejawnฤ… do klasy, w ktรณrej jej uลผywasz.

import StringUtil.StringEnhancer

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

Programowanie obiektowe (OOP) a programowanie funkcyjne (FP)

W programowaniu obiektowym programy sฤ… konstruowane przez grupyping Dane i funkcje operujฤ…ce na tych danych ล‚ฤ…czฤ… siฤ™ w silnie poล‚ฤ…czone jednostki. Obiekty przechowujฤ… swoje dane w polach, a metody na nich operujฤ…. W tym stylu programowania gล‚รณwnytracPodstawฤ… sฤ… dane, poniewaลผ tworzone metody majฤ… na celu operowanie na danych.

Programowanie funkcjonalneZ drugiej strony, oddziela dane i funkcje, ktรณre na nich operujฤ…. Dziฤ™ki temu programiล›ci mogฤ… traktowaฤ‡ funkcje jako abs.traccja i siล‚a napฤ™dowa przy modelowaniu programรณw.

Scala umoลผliwia programowanie funkcyjne, traktujฤ…c funkcje jako obywateli pierwszej klasy, umoลผliwiajฤ…c ich przekazywanie jako wartoล›ci do innych funkcji i zwracanie ich rรณwnieลผ jako wartoล›ci. Poล‚ฤ…czenie tych dwรณch paradygmatรณw sprawiล‚o, ลผe Scala jest doskonaล‚ym wyborem do tworzenia zล‚oลผonego oprogramowania w branลผach takich jak nauka o danych.

Waลผne frameworki w Scali

Oto kilka waลผnych struktur dla jฤ™zyka Scala:

  • Graj to platforma aplikacji internetowych o otwartym kodzie ลบrรณdล‚owym, ktรณra wykorzystuje Architektura MVCWydany w 2007 roku i obecnie licencjonowany na platformie Apache, do 2013 roku staล‚ siฤ™ jednym z najpopularniejszych frameworkรณw na platformie GitHub. Firmy takie jak LinkedIn, WalmartZ tego frameworka korzystajฤ… Samsung, Eero i Samsung.
  • Wyciฤ…g to kolejny darmowy framework webowy napisany w jฤ™zyku Scala, wydany w 2007 roku. Foursquare korzysta z frameworka Lift. Jest to wysoce wydajny framework, ktรณrego tworzenie jest szybkie.
  • Jak udostฤ™pnia zestaw narzฤ™dzi do tworzenia wysoce wspรณล‚bieลผnych, rozproszonych i odpornych aplikacji sterowanych komunikatami na maszynie wirtualnej Java (JVM).
  • koty jest bibliotekฤ…, ktรณra zapewnia abstraccje programowania funkcyjnego.
  • Spark jest zunifikowanym moduล‚em analitycznym do przetwarzania danych na duลผฤ… skalฤ™, powszechnie stosowanym w procesach przetwarzania duลผych zbiorรณw danych i uczenia maszynowego.

Wsparcie wspรณล‚bieลผnoล›ci

  • Wartoล›ci w Scali sฤ… domyล›lnie niezmienne, co sprawia, ลผe โ€‹โ€‹jฤ™zyk ten doskonale dopasowuje siฤ™ do ล›rodowisk wspรณล‚bieลผnych.
  • Scala ma wiele funkcji, ktรณre czyniฤ… jฤ… idealnฤ… do zastosowaล„ wspรณล‚bieลผnych.
  • Futures i Promises uล‚atwiajฤ… asynchroniczne przetwarzanie danych, wspierajฤ…c w ten sposรณb paralelizm.
  • Akka to zestaw narzฤ™dzi wykorzystujฤ…cy model wspรณล‚bieลผnoล›ci aktorรณw. Aktorzy podejmujฤ… dziaล‚ania po otrzymaniu wiadomoล›ci.
  • Wspรณล‚bieลผnoล›ฤ‡ przy uลผyciu wฤ…tkรณw z Java jest rรณwnieลผ obsล‚ugiwany w Scali.
  • Przetwarzanie strumieniowe to kolejna ล›wietna funkcja umoลผliwiajฤ…ca ciฤ…gล‚e przetwarzanie danych w czasie rzeczywistym.

Scala ma jedne z najlepszych bibliotek wspรณล‚bieลผnoล›ci na rynku Java ekosystem:

  • Tubylec Java wฤ…tki
  • Wล‚รณkna z bibliotek takich jak Vertx.
  • ZIO, biblioteka zawierajฤ…ca prymitywy uล‚atwiajฤ…ce radzenie sobie z obliczeniami wspรณล‚bieลผnymi i asynchronicznymi.
  • Pamiฤ™ฤ‡ transakcyjna oprogramowania (STM) dla transakcji.
  • Future, ktรณra jest wbudowana w jฤ™zyk Scala.

Java kontra Scala

Oto gล‚รณwne rรณลผnice pomiฤ™dzy Java i Scalฤ™.

Scala Java
Bardziej zwiฤ™zล‚e i zwiฤ™zล‚e. Stosunkowo wiฤ™ksze fragmenty kodu.
Zaprojektowany i opracowany jako obiektowy i funkcjonalny. Obsล‚uguje szerokฤ… gamฤ™ funkcji programowania funkcyjnego, takich jak wspรณล‚bieลผnoล›ฤ‡ i niezmiennoล›ฤ‡. Pierwotnie rozwijany jako jฤ™zyk obiektowy i w najnowszych wersjach zaczฤ…ล‚ obsล‚ugiwaฤ‡ funkcje programowania funkcyjnego. Nadal nie jest tak silny jak Scala w programowaniu funkcyjnym.
Uลผywa modelu aktora do obsล‚ugi wspรณล‚bieลผnoล›ci. Uลผywa konwencjonalnego modelu opartego na wฤ…tkach do wspรณล‚bieลผnoล›ci.
Obsล‚uguje frameworki takie jak Play i Lift. Obsล‚uguje Spring, Grails i wiele innych.
Wspiera leniwฤ… ocenฤ™. Nie obsล‚uguje natywnie leniwej oceny.
Brak elementรณw statycznych. Zawiera elementy statyczne.
Obsล‚uguje przeciฤ…ลผanie operatorรณw. Nie obsล‚uguje przeciฤ…ลผania operatora.
Kompilacja kodu ลบrรณdล‚owego jest stosunkowo powolna. Kompilacja kodu ลบrรณdล‚owego jest szybsza niลผ w Scali.
Cechy zachowujฤ… siฤ™ jak Java 8 interfejsรณw. Java 8 interfejsรณw ma na celu wypeล‚nienie luki miฤ™dzy klasami i interfejsami.
Czasami przy uaktualnianiu wersji konieczne jest ponowne napisanie kodu. Zazwyczaj nie jest konieczne ponowne przepisywanie miฤ™dzy wersjami.
Bezpieczeล„stwo typรณw zapewnia wysokฤ… niezawodnoล›ฤ‡ kodu, ale nie gwarantuje absolutnej braku bล‚ฤ™dรณw. Silne obciฤ…ลผenie statyczneping pomaga zredukowaฤ‡ wiele bล‚ฤ™dรณw w czasie wykonywania.
Ma pewne ograniczenia w zakresie wstecznej kompatybilnoล›ci pomiฤ™dzy gล‚รณwnymi wersjami. Silna, dล‚ugoterminowa kompatybilnoล›ฤ‡ wsteczna.
Operatory sฤ… traktowane jako wywoล‚ania metod. Operatory majฤ… specjalnฤ… skล‚adniฤ™ i nie sฤ… wywoล‚aniami metod.
Obsล‚uguje dziedziczenie wielokrotne za pomocฤ… cech. Nie obsล‚uguje wielokrotnego dziedziczenia za pomocฤ… klas; zamiast tego uลผywa interfejsรณw.
Code jest napisany w formie zwartej. Code jest napisane w bardziej szczegรณล‚owej formie.
Scala nie zawiera sล‚owa kluczowego static. Java zawiera sล‚owo kluczowe static.

FAQ

Scala ma bardziej stromฤ… krzywฤ… uczenia siฤ™ niลผ Java poniewaลผ ล‚ฤ…czy w sobie styl obiektowy i funkcjonalny. Jednak programiล›ci z Java Doล›wiadczeni zazwyczaj szybko przyswajajฤ… podstawy. ฤ†wicz na maล‚ych projektach, a Scala REPL przyspiesza naukฤ™.

Tak. Scala nadal napฤ™dza systemy na duลผฤ… skalฤ™ w firmach korzystajฤ…cych z Akki, Sparki Kafka. Popyt na nie utrzymuje siฤ™ w inลผynierii danych, fintech i systemach rozproszonych, gdzie wydajnoล›ฤ‡ JVM i programowanie funkcjonalne sฤ… cenne.

Tak. Wspรณล‚czeล›ni asystenci kodowania AI rozumiejฤ… skล‚adniฤ™ jฤ™zyka Scala, system typรณw i frameworki takie jak Akka i SparkPomagajฤ… generowaฤ‡ szablony, sugerujฤ… wzorce funkcjonalne, wyjaล›niajฤ… bล‚ฤ™dy kompilatora i refaktoryzujฤ… kod, przyspieszajฤ…c rozwรณj zarรณwno poczฤ…tkujฤ…cym, jak i ekspertom.

Scala napฤ™dza Apache'a Spark, wiodฤ…cy silnik do przetwarzania danych na duลผฤ… skalฤ™ w potokach AI. Biblioteki takie jak Breeze, Smile i Figaro obsล‚ugujฤ… obliczenia numeryczne, uczenie maszynowe i modelowanie probabilistyczne, co czyni Scalฤ™ doskonaล‚ym wyborem do analizy danych produkcyjnych.

Wartoล›ฤ‡ tworzy niezmienne powiฤ…zanie, ktรณre jest natychmiast oceniane. Zmienna tworzy zmienne powiฤ…zanie, ktรณre moลผna ponownie przypisaฤ‡. Leniwa wartoล›ฤ‡ wstrzymuje ocenฤ™ do momentu pierwszego dostฤ™pu do wartoล›ci, a nastฤ™pnie buforuje wynik do kolejnych odczytรณw.

Podsumuj ten post nastฤ™pujฤ…co: