could please explain why second call listen method not work , suggest solution make work?
object example extends app { case class event(kind: int) trait listener { def handle(e: event) } val listeners = scala.collection.mutable.map[int, listener]() def emit(e: event) = listeners.get(e.kind).foreach(_.handle(e)) def listen(kind: int)(f: (event) => unit) { val l = new listener() { override def handle(e: event) = f(e) } listeners += kind -> l } implicit def unit2eventunit(f: => unit) = (e: event) => f // works expected println("1") listen(1) { e: event => println("a"); println("b") } println("2") emit(new event(1)) println("3") // why not work? "c" should appear between "4" , "d", not "3" , "4" listen(2) { println("c"); println("d") } println("4") emit(new event(2)) println("5") }
i know work:
implicit def unit2eventunit2(f: () => unit) = (e: event) => f() listen(2) { () => println("c"); println("d") }
but simpler write:
listen(2) { println("c"); println("d") }
the compiler sees block in listen(2) { () => println("c"); println("d") }
. block not match signature of listen function, returns unit
, there implicit conversion unit
event => unit
, takes last expression in block , applies conversion. that's why result. don't see obvious solution this, ignore parameter in function , write as
listen(2) { _ => println("c"); println("d") }
then don't need implicit conversion. kind of conversions shouldn't used anyway, because make code hard reason people don't know of conversion , possible source unexpected behavior.
Comments
Post a Comment