"Funny" code
Functions are first class citizens in Scala. JVM, that doesn't know anything on Functions. All the magic is coming from the Scala Library and compiler. Sometimes we should know about "workarounds" were applied to support rich language features.
Lets look into the example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TestClass { | |
def func(inFunc: => Unit) { | |
println("Before") | |
try { inFunc } | |
catch { case _ => } | |
println("After") | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Program { | |
def main(args: Array[String]) { | |
val obj = new TestClass | |
obj func { println("inside") } | |
} | |
} |
Before
inside
After
Sweat, still code smells, but works as expected. And last one example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Program { | |
def main(args: Array[String]) { | |
val obj = new TestClass | |
obj func { println("inside"); return } | |
} | |
} |
Before
inside
After
After should not be here!
Return form closures rule
Return from closures must force return from the method that declared (wraps) closure. This part is really hard to get for Java dudes, that is why please look into example that makes it clean:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def isGreate0(list:List[Int]):Boolean = { | |
for (i <- list) | |
if (i <= 0) | |
return false | |
true | |
} |
Implemented via Exception
The only one way to stop a stack execution from any point is throwing an exception. As U already got try-catch construction eats an return Exception ( scala.util.control.ControlThrowable):
trait ControlThrowable extends Throwable with NoStackTrace
Of corse we should never use:
try {...} catch {case _ => }
Unfortunately it's equals to catch (Throwable e) in Java and will catch ControlThrowable((. _ is supporting compatibility with pattern matching, but Java error handling practices.
Enjoy the hacking Scala :p
But why it would return false? Shouldn't it be true if we just return from loop body and not from isGreate0 method?
ReplyDelete> If return didn't return from method but only from closure - method would always return false!