Хранение значения без использования val - PullRequest
0 голосов
/ 28 августа 2018

Предположим, есть 3 числа:

val x = 10
val y = 5
val z = 14

и мы хотим сделать логику вроде:

if (x + y > z) {
  println(x + y)
} else if (x + y < z) {
  println(-1)
} else {
  println(0)
}

Если наша операция "z + y" стоит дорого, мы должны вычислить ее ровно один раз:

val sum = x + y

if (sum > z) {
  println(sum)
} else if (sum < z) {
  println(-1)
} else {
  println(0)
}

но я хочу более функциональный способ, например:

if (x + y > z) => sum { //This is will not compile :)
  println(sum)
} else if (sum < z) {
  println(-1)
} else {
  println(0)
}

Что-то без необходимости другого оператора для сохранения результата. Что-то, что я могу соединить с другой функцией, например:

if(x + y > z) sum {
  if(sum + 10 > 100) other_sum {
... etc

PS. Совпадение не помогает:

x + y match {
  case result if result > z => println(result)
  case result if result < z => println(-1)
  case _ => println(0)
}

или

val sum = x + y
sum match {
  case _ if sum > z => println(sum)
  case _ if sum < z => println(-1)
  case _ => println(0)
}

Все равно выглядит плохо.

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Тим ответит правильно, но я бы добавил, что вам действительно нужно одно выражение . Вы заявили, что здесь, хотя вместо этого вы использовали слово «функция»:

То, что я могу соединить с другой функцией

Однако Scala уже основан на выражениях, так что на самом деле это одно выражение:

{
  val sum = x + y

  if (sum > z) {
    sum
  } else if (sum < z) {
    -1
  } else {
    0
  }
}

Возвращает либо sum, -1, либо 0. Вы даже можете напрямую передать этот результат в println. Фактически это эквивалентно вашему исходному коду:

println({
  val sum = x + y

  if (sum > z) {
    sum
  } else if (sum < z) {
    -1
  } else {
    0
  }
})
0 голосов
/ 13 сентября 2018

Почему вы пытались сравнить два значения типа int, если в scala есть класс неявного типа Ordering для Int и вы можете вызвать метод сравнения вместо кода выше? Использовать сравнение из компаратора Java

  (5 : Int).compare(9: Int) == -1

  def compare(that: A): Int
 /** Returns true if `this` is less than `that`
 */

 object Ordered {
 /** Lens from `Ordering[T]` to `Ordered[T]` */
 implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): 
 Ordered[T] = new Ordered[T] { def compare(that: T): Int = ord.compare(x, that)

Если вы хотите использовать странную логику, которую вы написали выше, вы можете создать собственную Упорядоченный неявный экземпляр и класс для u-упакованного значения, подобного этому

final case class V(value: Int)
  object V {
    def pure(v: Int): V[Int] = V(v)
    implicit orderV: Ordered[V] = (o: Ordered) => ???

     implicit class VOps(v: Int) extends AnyVal {
      def @(that: Int)(implicit o : Ordered[V]): Int = o.compareTo(pure(v), pure(that))
   }
  }

и после этого используйте вот так (x + y) @ z

0 голосов
/ 28 августа 2018

Вычисление sum во временной переменной не менее функционально, чем другие ваши решения. А если расчет сложный, то вы можете использовать имя временной переменной, чтобы описать результат и сделать код более читабельным.

Если вы хотите скомпоновать его с другим кодом, вы можете легко обернуть его в функцию.

Редактировать

Вот еще один способ избежать временной переменной, хотя она не обязательно лучше других.

((sum: Int) =>
  if (sum > z) {
    println(sum)
  } else if (sum < z) {
    println(-1)
  } else {
    println(0)
  }) (x + y)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...