Scala Cheatsheet
Scalacheat
Language
Contributed by Filip Czaplicki
Podziękowania dla Brendan O’Connor. Ten cheatsheet ma być szybkim podsumowaniem konstrukcji składniowych Scali. Licencjonowany przez Brendan O’Connor pod licencją CC-BY-SA 3.0.
zmienne | |
var x = 5 |
zmienna |
Dobrze val x = 5 Źle x=6 |
stała |
var x: Double = 5 |
zmienna z podanym typem |
funkcje | |
Dobrze def f(x: Int) = { x*x } Źle def f(x: Int) { x*x } |
definicja funkcji ukryty błąd: bez znaku = jest to procedura zwracająca Unit; powoduje to chaos |
Dobrze def f(x: Any) = println(x) Źle def f(x) = println(x) |
definicja funkcji błąd składni: potrzebne są typy dla każdego argumentu. |
type R = Double |
alias typu |
def f(x: R) vs.def f(x: => R) |
wywołanie przez wartość wywołanie przez nazwę (parametry leniwe) |
(x:R) => x*x |
funkcja anonimowa |
(1 to 5).map(_*2) vs.(1 to 5).reduceLeft( _+_ ) |
funkcja anonimowa: podkreślenie to argument pozycjonalny |
(1 to 5).map( x => x*x ) |
funkcja anonimowa: aby użyć argumentu dwa razy, musisz go nazwać. |
Dobrze (1 to 5).map(2*) Źle (1 to 5).map(*2) |
funkcja anonimowa: związana metoda infiksowa. Możesz użyć także 2*_ . |
(1 to 5).map { x => val y=x*2; println(y); y } |
funkcja anonimowa: z bloku zwracane jest ostatnie wyrażenie. |
(1 to 5) filter {_%2 == 0} map {_*2} |
funkcja anonimowa: styl potokowy. (lub ponawiasowane). |
def compose(g:R=>R, h:R=>R) = (x:R) => g(h(x)) val f = compose({_*2}, {_-1}) |
funkcja anonimowa: aby przekazać kilka bloków musisz użyć nawiasów. |
val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd |
rozwijanie funkcji, oczywista składnia. |
def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd |
rozwijanie funkcji, oczywista składnia. |
def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd |
rozwijanie funkcji, lukier składniowy. ale wtedy: |
val normer = zscore(7, 0.4) _ |
potrzeba wiodącego podkreślenia, aby wydobyć funkcję częściowo zaaplikowaną, tylko dla wersji z lukrem składniowym. |
def mapmake[T](g:T=>T)(seq: List[T]) = seq.map(g) |
typ generyczny. |
5.+(3); 5 + 3 (1 to 5) map (_*2) |
lukier składniowy dla operatorów infiksowych. |
def sum(args: Int*) = args.reduceLeft(_+_) |
zmienna liczba argumentów funkcji. |
pakiety | |
import scala.collection._ |
import wszystkiego z danego pakietu. |
import scala.collection.Vector import scala.collection.{Vector, Sequence} |
import selektywny. |
import scala.collection.{Vector => Vec28} |
import ze zmianą nazwy. |
import java.util.{Date => _, _} |
importowanie wszystkiego z java.util poza Date. |
package pkg na początku pliku package pkg { ... } |
deklaracja pakietu. |
struktury danych | |
(1,2,3) |
literał krotki. (Tuple3 ) |
var (x,y,z) = (1,2,3) |
przypisanie z podziałem: rozpakowywanie krotki przy pomocy dopasowywania wzorca. |
Źlevar x,y,z = (1,2,3) |
ukryty błąd: do każdego przypisana cała krotka. |
var xs = List(1,2,3) |
lista (niezmienna). |
xs(2) |
indeksowanie za pomocą nawiasów. (slajdy) |
1 :: List(2,3) |
operator dołożenia elementu na początek listy. |
1 to 5 to samo co 1 until 6 1 to 10 by 2 |
składnia dla przedziałów. |
() (puste nawiasy) |
jedyny obiekt typu Unit (podobnie jak void w C/Java). |
konstrukcje kontrolne | |
if (check) happy else sad |
warunek. |
if (check) happy to samo co if (check) happy else () |
lukier składniowy dla warunku. |
while (x < 5) { println(x); x += 1} |
pętla while. |
do { println(x); x += 1} while (x < 5) |
pętla do while. |
import scala.util.control.Breaks._ breakable { for (x <- xs) { if (Math.random < 0.1) break } } |
instrukcja przerwania pętli (break). (slides) |
for (x <- xs if x%2 == 0) yield x*10 to samo co xs.filter(_%2 == 0).map(_*10) |
instrukcja for: filtrowanie / mapowanie |
for ((x,y) <- xs zip ys) yield x*y to samo co (xs zip ys) map { case (x,y) => x*y } |
instrukcja for: przypisanie z podziałem |
for (x <- xs; y <- ys) yield x*y to samo co xs flatMap {x => ys map {y => x*y}} |
instrukcja for: iloczyn kartezjański |
for (x <- xs; y <- ys) { println("%d/%d = %.1f".format(x, y, x/y.toFloat)) } |
instrukcja for: imperatywnie sprintf-style |
for (i <- 1 to 5) { println(i) } |
instrukcja for: iterowanie aż do górnej granicy |
for (i <- 1 until 5) { println(i) } |
instrukcja for: iterowanie poniżej górnej granicy |
pattern matching (dopasowywanie wzorca) | |
Dobrze (xs zip ys) map { case (x,y) => x*y } Źle (xs zip ys) map( (x,y) => x*y ) |
używaj słowa kluczowego case w funkcjach w celu dopasowywania wzorca (pattern matching). |
Źleval v42 = 42 Some(3) match { case Some(v42) => println("42") case _ => println("Not 42") } |
“v42” jest interpretowane jako nazwa pasująca do każdej wartości typu Int, więc “42” zostaje wypisywane. |
Dobrzeval v42 = 42 Some(3) match { case Some(`v42`) => println("42") case _ => println("Not 42") } |
”`v42`” z grawisami jest interpretowane jako istniejąca wartość v42 , więc “Not 42” zostaje wypisywane. |
Dobrzeval UppercaseVal = 42 Some(3) match { case Some(UppercaseVal) => println("42") case _ => println("Not 42") } |
UppercaseVal jest traktowane jako istniejąca wartość, nie jako zmienna wzorca, bo zaczyna się z wielkiej litery. W takim razie wartość przechowywana w UppercaseVal jest porównywana z 3 , więc “Not 42” zostaje wypisywane. |
obiektowość | |
class C(x: R) to samo co class C(private val x: R) var c = new C(4) |
parametry konstruktora - prywatne |
class C(val x: R) var c = new C(4) c.x |
parametry konstruktora - publiczne |
class C(var x: R) { assert(x > 0, "positive please") var y = x val readonly = 5 private var secret = 1 def this = this(42) } |
konstruktor jest ciałem klasy deklaracja publicznego pola deklaracja publicznej stałej deklaracja pola prywatnego alternatywny konstruktor |
new{ ... } |
klasa anonimowa |
abstract class D { ... } |
definicja klasy abstrakcyjnej. (nie da się stworzyć obiektu tej klasy) |
class C extends D { ... } |
definicja klasy pochodnej. |
class D(var x: R) class C(x: R) extends D(x) |
dziedziczenie i parametry konstruktora. (wishlist: domyślne, automatyczne przekazywanie parametrów) |
object O extends D { ... } |
definicja singletona. (w stylu modułu) |
trait T { ... } class C extends T { ... } class C extends D with T { ... } |
cechy. interface’y z implementacją. bez parametrów konstruktora. możliwość mixin’ów. |
trait T1; trait T2 class C extends T1 with T2 class C extends D with T1 with T2 |
wiele cech. |
class C extends D { override def f = ...} |
w przeciążeniach funkcji wymagane jest słowo kluczowe override. |
new java.io.File("f") |
tworzenie obiektu. |
Źle new List[Int] Dobrze List(1,2,3) |
błąd typu: typ abstrakcyjny zamiast tego konwencja: wywoływalna fabryka przysłaniająca typ |
classOf[String] |
literał klasy. |
x.isInstanceOf[String] |
sprawdzenie typu (w czasie wykonania) |
x.asInstanceOf[String] |
rzutowanie typu (w czasie wykonania) |
x: String |
oznaczenie typu (w czasie kompilacji) |