2010. febr. 24. 8:00 - írta kieszistvan

Szvsz az egyik legjobb dolog amivel eddig találkoztam Scala-ban. Bármire ráellenőrizhetünk anélkül, hogy hosszasan kódolnánk. Az utasítás megegyezik a Java switch utasításával, kivéve hogy lényegesen többet "tud" plusz nincs szükség brake-re, mivel a folyamat nem falltrough. De beszéljen a kód helyettem:

def patternMatching(x: Any): Unit = {
10 match {
case 10 => "tíz"
case _ => "más"
}

"tíz" match {
case "tíz" => 10
case _ => 0
}

Person("adam", 30) match {
case Person("adam", _) => "Adam is 30"
case _ => "nooooo"
}

Person("adam", 30) match {
case Person("adam", age) => "Adam is "+ age
case _ => "nooooo"
}

100 match {
case szam if szam > 100 => "nagyobb száz"
case _ => "kisebb száz"
}

x match {
case s: String => "ő egy String"+ s
case i: Int => "ő egy Int"+ i
case _ => "egyik sem"
} // ugye mindenki ideképzelte az instanceof-okat :)
}

A Person az ezelőtti post case class-e. Ami Java-hoz képest más az a String-re való ellenőrzés, ellenőrizhetünk case class-re is, valamint a '_' joker karakter, ami körülbelül a "bármi"-nek felel meg. A beérkező paramétert változóként is használhatjuk (lásd Person("adam", 30), majd Person("adam", age)). Lehetőség van if beágyazására és típus ellenőrzésre (btw Scala egyben castolja is az x-emet Int-re ha kell).

U.i.: úgydöntöttem, hogy összevissza fogom használni a Scala szintaxisát, mert egyelőre azt látom, hogy mindenki másképp használja. Van aki void metódusokhoz odateszi hogy def meth():Unit = {}, van aki nem. Van aki val a: String = "valami"-t használ van aki val a = "valami"-t stb. A saját érdekembe döntöttem így, meg persze azért, hogy aki olvassa az is hozzászokjon a változatos kódokhoz.


 
 
0 (0)
Jelentkezz be a szavazáshoz!
2010. febr. 23. 8:00 - írta kieszistvan

Scala case class-ek lényege, hogy elkerüljük a felesleges kód(boilerplate) írását. Nincs szükség a toString, hashCode, "equals" felülírására, ezeket a compiler kigenerálja nekünk. Egyszerűen, new kulcsszó nélkül hozhatunk létre ilyen - JavaBean-hez hasonló - osztályokat. Például legyen egy embereket leíró osztályunk:

case class Person(name: String, age: Int)

Hozzunk létre egy példányt belőle és írassuk ki a metódusaink visszatérési értékét:

val adam = Person("Adam", 30)
println(adam.toString)
println(adam.name)
println(adam.age)
println(adam == Person("Adam", 30))
println(adam == Person("adam", 30))

Kimenet:
Person(Adam,30)
Adam
30
true
false

Ugyanígy elérjük az osztályunk propertie-it, valamint Scala pattern matching-et is használhatjuk, amiről később írok:

adam.name
adam.age

 
 
0 (0)
Jelentkezz be a szavazáshoz!
2010. febr. 22. 8:00 - írta kieszistvan

Mivel Scala funkcionális nyelv (is), ezért lehetőségünk van rá, hogy függvényeket adjunk át metódusoknak. Scala a függvényeket egy bizonyos interface-t implemenátló osztályként kezeli. Nézzük meg az egyparaméteres trait-ünket ami egy funkciót definiál Function1[A, B]. Ez esetben A a paraméter típus és B a visszatérési érték típusa. Minden funkció implementálja az apply metódust. Function1-nél ez úgy néz ki hogy Function1.apply(par: A): B.

A nyelv szintaxisának sajátossága, hogy ha egy metódusunk bemeneti típusa egy function (

def someMethod(f: Function[Int, String]) = f.apply(100)

), akkor nincs szükség a paraméteren történő apply hívásra, hanem elég a következő: f(100).

A function-ünket leírhatjuk így is: def someMethod(f: Int => String) = f(100)

Minden osztály, aminek van apply metódusa meghívható ilyetén formában.

class ApplyClass  {
def apply(in: Int): String = in.toString
}

val ac = new ApplyClass
ac(100)  // figyeljük meg, hogy ac példány apply-ja
// már a 100-as szám karakterreprezentációját adja vissza


Van még a tarsolyban. Fontos szerepe van az update nevű metódusnak is egy osztályon belül. Update átalában két paramétert vár és akkor hívódik, amikor (csúnyán fogalmazva) a metódusunk egy értéket kap. Legjellemzőbb példa az Array és HashMap. Nézzük meg az alábbi kódot és kimenetét és máris rájövünk a lényegére:

class Update {
def update(a: String) = println("Egy paraméter: "+ a)
def update(a: Int, b: Int, c: String) =
println("Három paraméter: "+ a +" "+ b +" "+ c)
}

val u = new Update
u() = "Foo"
u(1, 2) = "Bar"

A kimenet pedig:
Egy paraméter: Foo
Három paraméter: 1 2 Bar

HashMap esetén egy K V párunk lesz és a hívás a következő lenne: u(key) = value, ahol key mondjuk egy Int és value egy String


 
 
0 (0)
Jelentkezz be a szavazáshoz!
2010. febr. 21. 12:53 - írta kieszistvan

Java pass-by-value (igen, reference is reference value-ként adódik át) után újdonságként szolgált a pass-by-name(vagy call-by-value, ahogy nézzük). Ebben az esetben a komplett kódblokk adódik át a metódusunknak. Egy példa:

class A {
def callByName(par: => Long) = {
println("callByName metódus")
par
}

def sysDate = {
println("sysDate metódus")
System.nanoTime
}
}


Hívjuk is meg:

val a = new A
a.callByName(a.sysDate)

Az eredmény ez lesz:
callByName metódus
sysDate metódus
123456789  // aktuális idő

Ilyenkor kvázi a metódus adódik tovább tehát az átadott blokk hívása a hívó blokkban, azaz a callByName blokkban történik. Ha kihagyjuk a '=>' operátort a metódusleíróból, abban az esetben először meghívódik a sysDate, majd az ő visszatérési értékével fut le a callByName-ünk.


 
 
0 (0)
Jelentkezz be a szavazáshoz!