不使用val来存储值

时间:2018-08-28 07:21:29

标签: scala functional-programming

假设有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 :(得分:5)

计算临时变量中的sum的功能与其他解决方案一样。而且,如果计算复杂,则可以使用临时变量的名称来描述结果,并使代码更具可读性。

如果要将其与其他代码组成,则可以轻松地将其包装在函数中。

编辑

这是避免临时变量的另一种方法,尽管不一定比其他方法好。

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

答案 1 :(得分:5)

蒂姆的答案是正确的,但我要补充一点,您真正想要的是一个表达式。您在这里表示的是,尽管您改用了“功能”一词:

  

可以与其他功能配合的东西

但是,Scala已经基于表达式,因此它实际上是一个表达式:

{
  val sum = x + y

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

它返回sum-10。您甚至可以将结果直接传递给println。实际上,这等效于您的原始代码:

println({
  val sum = x + y

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

答案 2 :(得分:0)

如果scala具有Int的Ordering隐式类型类,并且为什么可以调用compare方法而不是上面的代码,为什么还要尝试比较两个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