------------------------------------------- Metodo apply ___________________________________________ ApplyClassMain.scala case class MiaLista[T](l:List[T]) { def apply(i:Int) = l(i) } object ApplyClassMain extends App { val l = List(7,2,3,4,1) val q = MiaLista(l) println(l(1)) println(q.apply(1)) println(q(1)) // equivalente alla riga precedente } ___________________________________________ ApplyObjectMain.scala class Persona(val nome:String) object Persona { def apply(n:String) = new Persona(n) } object ApplyObjectMain extends App { val p = new Persona("Paola") val q = Persona.apply("Marco") val r = Persona("Francesca") println(p.nome) println(q.nome) println(r.nome) } ------------------------------------------- Passaggio dei parametri per nome ___________________________________________ CallByNameMain.scala object CallByNameMain extends App { def p(x:Int) = { println(x) x } // semantica di if ... else nativa di Scala println("Test if ... else:") val t = if (true) p(10) else p(20) val f = if (false) p(10) else p(20) println(t + " - " + f) // versione con semantica errata def myIfElseKO(a:Int, b:Int, test:Boolean) = if (test) a else b println("Test myIfElseKO:") val tko = myIfElseKO(p(10), p(20), true) val fko = myIfElseKO(p(10), p(20), false) println(tko + " - " + fko) // versione con semantica corretta def myIfElseOK(a: =>Int, b: =>Int, test: =>Boolean) = if (test) a else b println("Test myIfElseOK:") val tok = myIfElseOK(p(10), p(20), true) val fok = myIfElseOK(p(10), p(20), false) println(tok + " - " + fok) } ------------------------------------------- Definizione di nuovi costrutti: ___________________________________________ MyRepeatMain.scala object MyRepeatMain extends App { // versione che ripete un numero di volte pari // al valore iniziale di n def ripeti(n:Int)(body: =>Unit) = (1 to n).foreach(i => body) // versione "dinamica" che ripete un numero di volte che // varia al variare di n - implementazione imperativa def ripeti2(n: =>Int)(body: =>Unit) = { var count = 0 while (count < n) { body count = count + 1 } } // versione "dinamica" che ripete un numero di volte che // varia al variare di n - implementazione funzionale def ripeti3(n: =>Int)(body: =>Unit) = { def aux(count:Int):Unit = if (count>n) () else { body aux(count+1) } aux(1) } println("Ripetizioni prefissate:") ripeti(5) { println("ciao") } ripeti(5)(println("ciao")) // equivalente alla precedente println("Ripetizioni non prefissate:") var i = 10 ripeti3(i) { // confronta risultati con ripeti e ripeti2 println(i) i = i - 2 } } ------------------------------------------- Uso di metodi implicit per "iniettare" funzionalità in classi esistenti: Esempio: "aggiunta" di un metodo mymap alla classe List. ___________________________________________ MiaLista.scala import scala.language.implicitConversions class MiaLista[T](l:List[T]) { def mymap[S](f:T=>S):List[S] = l.map(f) // ... } object MiaLista { implicit def listToMiaLista[T](l:List[T]) = new MiaLista(l) } ___________________________________________ MiaListaMain.scala import MiaLista._ object MiaListaMain extends App { val l = List(1,2,3,4) val q = l.mymap(_*2) println(q) }