04 - false and loop

Láttuk, hogy függvényeket a def kulcsszóval vezetünk be, nézzünk erre pár példát.

Az előadás alapján egy függvényt, ami összead két intet, így írnánk meg:

1
2
3
def osszeAd(x: Int, y: Int): Int = {
  x+y
}

Ezzel kapcsolatban amit érdemes észben tartanunk:

  • Ha a függvénytörzsben lévő kifejezés típusát ki tudja következtetni a Scala és az nekünk megfelel, nem kell kiírnunk a függvény visszatérési értékét.
  • Ha a függvénytörzsben egyetlen kifejezés szerepel, akkor nem kell kitegyük a kapcsos zárójeleket.
  • Ha a függvény nem vár egyetlen argumentumot sem, akkor nem kell kitegyük a () jelet a függvény neve mögé (és ekkor meghívni is enélkül tudjuk.)

Próbáljuk is ki:

1
2
3
def osszeAd(x: Int, y: Int) = x+y

println( osszead(2,3) ) //prints 5

Az osszeAd függvény kimeneti típusát tehát a fordító Intre inferreli nekünk, ezt az idea szürkével jelzi is:

inferred Int

Tipikusan a rekurzív függvények azok, melyeknek a Scala nem fog tudni automatikusan típust inferrelni.

A paraméter nélküli függvényekkel kapcsolatban a Scala style guide (note: érdemes nézegetni a Scala coding konvenciókat ezen az oldalon, sokkal olvashatóbb kódot tud írni az ember, ha betartja azokat az ajánlásokat, melyeket többé-kevésbé mindenki betart, és Scalában a kód jó olvashatósága must have) azt írja, hogy

  • ha a metódus, melynek nincs paramétere, nem rendelkezik mellékhatással és tényleg csak egy értéket ad vissza, akkor hagyjuk el a nyitó-csukójeleket,
  • de ha van mellékhatása (pl a println() ilyen: visszaadja a () értéket, ami az egyetlen Unit típusú érték, de közben üt egy újsort a konzolra ,,mellékhatásként''), akkor tegyük ki a zárójeleket!

Kérdések, feladatok

  • Írjunk egy loop függvényt, ami típusát tekintve Booleant ad vissza, de mindig végtelen ciklusba esik.
    válasz mutatása
1
def loop: Boolean = loop
  • Írjunk egy and függvényt, ami két Boolean kifejezést vár, és pontosan akkor ad vissza truet, ha mindkettő értéke true. Legyen gyorsított kiértékelés: ha az első argumentum értéke false, akkor a másodikat ki se értékelje.
    válasz mutatása
1
def and(x: Boolean, y: =>Boolean) = if(x) y else false 
  • Az előző kérdés minta megoldásának miért lehet a második paraméter típusa olyan, amilyen?

    válasz mutatása Az x argumentum értékét mindenképpen használjuk egyszer, ezért ez call-by-value lett; az y argumentum értékét viszont vagy egyszer, vagy nullaszor, ez ezért lett call-by-name.

  • Tudsz olyan hívást mondani, ahol az and függvény másképp viselkedik, ha call-by-name vagy call-by-value kezeljük a paramétereket?

    válasz mutatása and(false,loop) például végtelen ciklusba esik, ha érték szerint adjuk át a második paramétert. Ha név szerint, akkor nem: működik a gyorsított kiértékelés a call-by-name konvenció miatt.

  • Implementáld le az and, or, not, implies, iff, xor logikai műveleteket is, ott használva gyorsított kiértékelést, ahol csak lehet. (STEPIK)


Utolsó frissítés: 2020-12-22 21:04:26