`return` в литерале функции scala

Я пытаюсь сделать что-то вроде этого:

var fun : (Int,Int) => Double = (a,b) =>
{
  // do something
  return 1.0
}

Тем не менее, мои жалобы IDE с Return statement outside method definition, Итак, как мне явно дать оператор return в литерале функции в scala?

4 ответа

Решение

В Скала return оператор возвращается из тела включающего метода. Если return появляется внутри литерала функции, это реализовано с использованием исключения. return вызовет исключение внутри функции, которое затем будет перехвачено методом включения. Scala работает таким образом, чтобы сделать использование пользовательских управляющих конструкций, которые принимают функции невидимыми, например:

def geometricAverage(l: List[Double]): Double = {
  val product = l.foldLeft(1.0) { (z, x) =>
    if (x == 0) return 0 else z * x
  }
  Math.pow(product, 1.0 / l.length)
}

return в этом примере возвращается из geometricAverage метод, позволяющий завершить его немедленно, если найден 0. Вам не нужно знать, что foldLeft это метод, который принимает функцию, а не встроенную конструкцию для реализации этого.

В Scala предпочтение отдается написанию функций в функциональном стиле, используя преимущества ориентированной на выражения природы Scala для создания return ненужным. Например:

val fun: (Int,Int) => Double = (a,b) => {
  if (a == b) {
    // side effect here, if desired
    0.0
  } else {
    // side effect here, if desired
    1.0
  }
}

Если вы действительно хотите использовать return в определении функции вы можете реализовать соответствующий интерфейс функции вручную вместо использования литерала функции:

val fun = new Function2[Int, Int, Double] {
  def apply(x: Int, y: Int): Double = {
    if (x == y)
      return 0.0
    1.0
  }
}

Но это не идиоматично и категорически не рекомендуется.

Не используйте возврат, это заставляет Scala плакать.

scala> var fun: (Int, Int) => Double = (a, b) => {
     | // do something
     | 1.0
     | }
fun: (Int, Int) => Double = <function2>

scala> fun(1, 2)
res4: Double = 1.0

Или еще лучше:

scala> def fun: (Int, Int) => Double = (a, b) => {
     | // do something
     | 1.0
     | }
fun: (Int, Int) => Double

scala> fun(1, 2)
res4: Double = 1.0

Как явно указать оператор возврата в литерале функции в Scala?

Ты не можешь На это отвечает раздел спецификации языка 6.20 " Выражения возврата":

Выражение возврата return e должен присутствовать внутри тела какого-либо вложенного именованного метода или функции.

apply Метод, который генерируется компилятором как расширение анонимной функции, не считается как именованная функция в исходной программе и поэтому никогда не является целью возвращаемого выражения.

Здесь нет return Заявление в Скала. В любой функции последний выполненный оператор является возвращаемым значением. Если это последнее утверждение не соответствует ожидаемому типу возврата функции, компилятор выдаст ошибку.

Другие вопросы по тегам