Vir

Takie zwykłe blogowanie.

Scala

Dziś chciałbym przedstawić wszystkim tutorial odnośnie języka Scala.

Instalacja

Instalację Scali możemy przeprowadzić na różne sposoby.

curl -fL https://github.com/coursier/coursier/releases/latest/download/cs-x86_64-pc-linux.gz | gzip -d > cs && chmod +x cs && ./cs setup

To jest instalacja w systemie Linux. Na oficjalnej stronie języka Scala czyli https://www.scala-lang.org/download/ mamy instrukcję instalacji na wszystkie systemy operacyjne. Czyli instalacja przez brew na macOS, instalka dla Windowsa i inne.

Dobrze jest też mieć zainstalowaną Javę.

sudo apt-get install default-jdk

Następnie wpisujemy polecenie: sudo apt-get install scala

Środowisko programistyczne

Są różne sposoby uruchamiana programów napisanych w języku Scala. Ja uważam, że obecnie najlepszym jest używanie środowiska programistycznego. Polecam Intellij Idea Community. To akurat środowisko jest w pełni darmowe i ma wiele ciekawych funkcji. Można je pobrać ze strony internetowej https://www.jetbrains.com/idea/download/?section=linux. Istnieje też wersja Ultimate, ale do Scali wystarczy ta wersja Community.

Projekt

No to tworzymy projekt. Mamy zainstalowany Intellij. Uruchamiamy środowisko. Znajdujemy opcję New > Project czy coś takiego. Wybieramy opcję Scala, czyli że chcemy utworzyć projekt w języku Scala. Wybieramy SDK. Jak nie mamy to środowisko może pomóc nam je zainstalować. Dajemy nazwę projektu i tworzymy nasz pierwszy projekt w języku Scala.

Klasa Main

Na razie nie będę wnikał w klasy. Jest to część języka Scala. Na tą chwilę powinno być to wiadome, że każdy projekt posiada klasę uruchomieniową. Najlepiej nazwać ją Main, co oznacza, że jest to klasa główna, która uruchamia program, nasz program. Otwieramy ją. W niej mamy metodę main(). Niby ta klasa to jest tzw. object, no ale to też jest klasa. W metodzie main() wpisujemy wszystkie instrukcje, które chcemy uruchomić. Następnie naciskamy kombinację Shift + F10 i uruchamiamy program.

Klasy

A więc tak, w języku Scala istnieją tzw. klasy. Klasa definiuje obiekt. Zawiera metody, które definiują zachowanie obiektu. W folderze src tworzymy nowe pakiety i klasy. Kiedyś pakiety oznaczało się w taki sposób: com.domena.modul. Teraz to jest dowolne. Czyli prawy przycisk myszy na folder src > New > package. Nazywamy pakiet. W tym pakiecie tworzymy klasę, czyli new > Scala class. Dobrze by było gdyby nazwy klas zaczynały się wielką literą i odwzorowywały to co robi dana klasa. Czyli jak np. klasa wyświetla tekst to nazwiemy ją powiedzmy drukarka.

W klasie tworzymy metodę. Tworzymy ją tak: def ( < argumenty > ) : < wartosc_zwracana > { cialo_metody }. Moja klasa na potrzeby kursu wygląda w ten sposób:

package kurs

class Kurs {

def wyswietlanie(): Unit = {

}

}

Ta metoda jeszcze nic nie robi. No to napiszę w niej sobie instrukcję, która wyświetla dowolny tekst. W Scali jest to instrukcja println().

package kurs

class Kurs {

def wyswietlanie(): Unit = {
println("Witaj Scala!")
}

}

No dobra, jest klasa, jest metoda, ale trzeba ją jeszcze uruchomić. Przechodzę do klasy Main i tworzę odpowiednie instrukcje. Podaję obiekt i uruchamiam metodę. Obiekty mają takie przyjęte w Scali dwa typy: val i var. Obiekt val tworzymy raz i jego instancji już nie zmieniamy, a w obiekcie var możemy zmieniać instancję. Czyli w metodzie main() klasy Main tworzymy obiekt: val kurs = new Kurs. Następnie wywołujemy metodę wyświetlanie: kurs.wyswietlanie(). Możemy uruchomić program.

Spośród różnych typów danych możemy wymienić:

Wszystkie jednak typy oznacza się przez val lub var. Jak dodatkowo chcemy oznaczyć typ zmiennej to robimy to w ten sposób: var zmienna: Double = 0.0d.

To co, można wykonywać typowe operacje arytmetyczne. Można wykonywać rozszerzone działania przez bibliotekę math. Jest obsługa plików, listy, tablice. Można powiedzieć, że Scala to taka Java na resorach. To co parę przykładzików.

Pobieranie informacji

def pobierz_info(): Unit = {
var znaki = ""
print("Podaj swoje imię: ")
znaki = scala.io.StdIn.readLine()
println("Witaj " + znaki)
}

Tą metodę można sobie skopiować i wkleić do poprzedniej klasy. Metoda pobiera imię od użytkownika. Imię wpisuje się z klawiatury.

Kalkulator

Uczyńmy więc sobie prosty kalkulator, na nasze podobieństwo, podobnemu kalkulatorowi np. z Windowsów, itd.

def dzialanie(zm1: Double, zm2: Double, dz: String): Double = {
var wynik: Double = 0.0d
if (dz.compareTo("+") == 0) { wynik = zm1 + zm2 }
if (dz.compareTo("-") == 0) { wynik = zm1 - zm2 }
if (dz.compareTo("*") == 0) { wynik = zm1 * zm2 }
if (dz.compareTo("/") == 0) { wynik = zm1 / zm2 }
if (dz.compareTo("%") == 0) { wynik = zm1 % zm2 }
wynik
}

Tu już użyłem instrukcji if. Można użyć if-else. Czyli mamy trzy argumenty. Pierwszy i drugi to składniki działania, a trzeci wskazuje na rodzaj działania jakie chcemy wykonać. Widać metoda zwraca obiekt typu Double. Dosyć ciekawa metoda.

Listy

Scala ma wiele rodzajów list. Ja tutaj właśnie znalazłem bardzo ciekawy rodzaj listy o nazwie ListBuffer. Używam go i powiem, że jak dla mnie najlepszy rodzaj spośród wszystkich list. Intellij wyświetla mi tutaj aż 22 rodzaje tzw. Tupli. Sporo. No ale nic, przejdźmy do sedna.

var lista = new ListBuffer[Double]. W nawiasie kwadratowym podaję typ danych.

Są to takie podstawowe metody dla listy.

Pętle

Pętla to taka instrukcja, która powstarza się sama określoną ilość razy. Pętla while:

def petla(): Unit = {
var indeks = 0

while ( indeks < 10 ) {
println(indeks)
indeks = indeks + 1
}
}

W pętli for możemy odczytać całą listę:

for (element <- lista) {
println(element)
}

Wątki

Wątki to obiekty, które mogą zostać uruchomione w tym samym czasie.

class Watek extends Thread {

override def run(): Unit = {
println("Wątek")
}

}

Metoda main():

var watek1 = new Watek
var watek2 = new Watek
var watek3 = new Watek

watek1.start()
watek2.start()
watek3.start()

Jak widać klasa Watek dziedziczy po klasie Thread. Dziedziczymy poprzez dopisanie słowa kluczowego extends. Następnie nadpisujemy metodę override i tam właśnie mówimy wątkowi co ma robić. Możemy wątki spakować do listy i uruchamiać kiedy chcemy.

Pliki

Działania na plikach w Scali są dosyć proste.

Zapis pliku

var sciezka = "plik1.txt" var dane = "Siała baba mak\nNie wiedziała jak" new PrintWriter(sciezka) { write( dane ); close() }

Odczyt pliku

def odczytaj_plik (sciezka: String = ""): ListBuffer[String] = {
val zrodlo: BufferedSource = Source.fromFile(sciezka);
val lista = ListBuffer("")
lista.remove(0)

try {
for (linia <- zrodlo.getLines()) {
lista += linia
}
} finally {
zrodlo.close()
}

lista
}

A wkleiłem już całą metodę, niech będzie.

Usuwanie plików.

var plik = new File(sciezka)
val istnieje = plik.exists()
if ( istnieje ) {
plik.delete()

Lista plików.

val folder: File = new File(sciezka)
var lista = folder.list().toList

Plik istnieje.

val plik = new File(sciezka)
val istnieje = plik.exists()

Stworzenie folderu.

new File(sciezka).mkdir()

Data

Chcemy wyświetlić datę w Scali? Nie ma problemu. Użyjmy do tego klasy ZonedDateTime.

Dalej nie pokazuję, bo są od tego dokumentacje.

Grafika

val size = (500, 500)
val canvas = new BufferedImage(size._1, size._2, BufferedImage.TYPE_INT_RGB)
val g = canvas.createGraphics()
g.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON) // antialiasing

g.setColor(Color.CYAN)
g.fill(new Rectangle2D.Double(20.0, 400.0, 50.0, 20.0)) // prostokat
g.draw(new Rectangle2D.Double(400.0, 400.0, 50.0, 20.0)) // prostokat bez wypelnienia

g.setColor(new Color(0, 0, 255))
g.draw(new Line2D.Double(50.0, 50.0, 250.0, 400.0)) // linia

// teksty
g.setColor(new Color(0, 128, 0))
g.setFont(new Font("Batang", Font.PLAIN, 20))
g.drawString("Hello World!", 155, 225)
g.drawString("안녕 하세요", 175, 245)

g.setColor(Color.RED)
g.fill(new Ellipse2D.Double(30.0, 30.0, 40.0, 40.0)) // elipsa
g.fill(new Ellipse2D.Double(230.0, 380.0, 40.0, 40.0))

g.dispose() // zakonczenie rysowania
javax.imageio.ImageIO.write(canvas, "png", new java.io.File("drawing.png")) // zapisanie grafiki do pliku

Interfejs

Interfejs graficzny pomaga w zarządzaniu naszym programem.

var frame = new JFrame();
frame.setSize(350, 350);
frame.setDefaultCloseOperation(2);
frame.setTitle("Okno");
frame.setVisible(true);