代码之家  ›  专栏  ›  技术社区  ›  HoTicE

不使用VAL存储值

  •  2
  • HoTicE  · 技术社区  · 6 年前

    假设有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 回复  |  直到 6 年前
        1
  •  5
  •   Tim    6 年前

    计算 sum 在一个临时变量中,它的功能不亚于其他解决方案。如果计算很复杂,那么可以使用临时变量的名称来描述结果,并使代码更具可读性。

    如果您想用其他代码组合它,那么您可以很容易地将它包装在一个函数中。

    编辑

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

    ((sum: Int) =>
      if (sum > z) {
        println(sum)
      } else if (sum < z) {
        println(-1)
      } else {
        println(0)
      }) (x + y)
    
        2
  •  5
  •   Brian McCutchon    6 年前

    蒂姆的回答是对的,但我想补充一下,你真正想要的是一个 表达 . 你在这里说,尽管你用了“函数”这个词:

    我可以用另一个函数复合的东西

    但是,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
      }
    })
    
        3
  •  0
  •   Mikhail Nemenko    6 年前

    如果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