【问题标题】:Why a block variable in scala function could not update after executed the inner block(s)?为什么 scala 函数中的块变量在执行内部块后无法更新?
【发布时间】:2016-07-14 12:00:05
【问题描述】:

我是 scala 的新手。我编写了一个名为 calculateSubTotal 的函数,其中包含产品 ID 和数量列表。

首先,该函数将从数据库中为每个产品 id 挑选一个产品,然后计算individual sub total 并与sub total 相加。我想返回计算的小计。计算没问题,但不幸的是它返回initialized value 而不是calculated value。我的代码怎么了。代码如下:-

def calculateSubTotal(productIds: Seq[Int], quantities: Seq[Int]) = {
  var subTotal = 0.0
  for (index <- 0 to productIds.length - 1) {
    val productId = productIds(index)
    val quantity  = quantities(index)
    val futureProduct = Products.read(productId)
    for {
      product <- futureProduct
    } yield {
      val listPrice = product.get.listPrice
      subTotal += listPrice * quantity
    }
  }
  subTotal
}

看上面的函数总是返回 0.0,因为我已经初始化了。正确的代码是什么?

【问题讨论】:

  • Products.read() 方法的结果类型是什么?是Future[Option[Product]]吗?
  • 是的 ... Products.read() 返回 Future[Option[Product]] @PawełJurczenko

标签: playframework-2.0 postgresql-9.4 slick-3.0


【解决方案1】:

问题是您的Products.read() 方法的结果类型是Future[Option[Product]],这意味着在您当前的代码中它在不同的线程上执行。主线程(执行calculateSubTotal 的线程)不会等待Products.read() 的成功执行,它会立即返回结果(在这种情况下为subTotal)。这将允许不确定的结果:有时subTotal 根本不会被修改,有时会被部分修改,有时你会得到正确的结果。最简单的解决方案是同步等待Products.read() 结果:

import scala.concurrent.duration.Duration
import scala.concurrent.Await

Await.result(Products.read(productId), Duration.Inf)

异步解决方案需要以某种方式重写calculateSubTotal,从而返回Future[Int]

【讨论】:

    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多