user266003
user266003

Reputation:

Return from "for" in Scala is not the same as return from "for" in Java

I have a Java code which I want to convert to Scala one:

    MyClass myMethod(String str1) {
      for (Item item: items) {
        if (/* some condition */) {
          if(/* another condition */) {
            return item.myMethod123();
          }
        }
     }

     return super.myMethod(str1);   
   }

If I use for in Scala, it will be translated to map, that is calling return within map will just return value from map, but it won't stop myMethod execution. But I want it to behave exactly like it does in this Java code.

How do I solve this?

UPDATE: I mean, I have to use foreach instead of for. However, calling return from foreach is just returning value from foreach and not stopping myMethod execution.

UPDATE2: I'm confused, foreach doesn't return any value.

Upvotes: 0

Views: 174

Answers (1)

Rex Kerr
Rex Kerr

Reputation: 167891

It in fact will stop myMethod execution because behind the scenes it actually throws a (no-stack-trace) exception which is caught by myMethod before actually returning. So you just

def myMethod(str1: String) {
  for (item <- items) {
    if (/*some cond*/) {
      if (/*other cond*/) {
        return item.myMethod123
      }
    }
  }
  super.myMethod(str1)
}

"just like" in Java.

The code works fine; it just doesn't work as fast since there is an exception involved. (Stack traces are what take most of the time, so you're probably okay here unless it's a heavily-used loop.)

Alternatively, you can

val target = items.find{ item => 
  if (/* some cond */) { 
    /*other cond*/
  }
  else false
}
target.map(_.myMethod123()).getOrElse(super.myMethod(str1))

which will first pick out that item on which you can call a method, or will default to super if there is no such item.

Upvotes: 6

Related Questions