2013-06-22 1 views
0

У меня есть код Java, который я хочу, чтобы преобразовать в Scala один:Возвращение из «за» в Scala не то же самое, как возвращение из «за» в Java

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

    return super.myMethod(str1); 
    } 

Если я использую for в Scala, он будет переведен на map, то есть на вызов return в пределах map будет просто возвращено значение от map, но оно не остановится myMethod исполнение. Но я хочу, чтобы он вел себя точно так же, как в этом коде Java.

Как это решить?

UPDATE: Я имею в виду, я должен использовать foreach вместо for. Однако вызов return от foreach только что возвращает значение от foreach и не останавливается myMethod исполнение.

UPDATE2: Я смущен, foreach не возвращает никакой ценности.

+1

Можете ли вы показать свой пробный код scala? – fge

+0

foreach не похож на java выражение, его функцию на коллекции, которая будет просто вызывать функцию для каждого элемента внутри вашей карты, todo, как java, вам также нужно использовать выражение for, например @ rex-kerr, объясняющее –

+0

'элементов. find (item =>/* некоторое условие */&&/* другое условие * /). fold (super.myMethod (str1)) (_. myMethod123()) ' –

ответ

7

Это ведь будет остановить myMethod исполнения, потому что за кулисами он на самом деле не бросает (нет-стеки, следа) исключение, которое перехватывается myMethod до фактического возвращения. Таким образом, вы просто

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

"just like" in Java.

Код работает нормально; он просто не работает так быстро, поскольку есть исключение. (Stack следы того, что берут на себя большую часть времени, так что вы, вероятно, хорошо здесь, если это не сильно используемый цикл.)

В качестве альтернативы, вы можете

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

, который будет первым выбрать этот пункт который вы можете вызвать методом, или по умолчанию будет супер, если такого элемента нет.