为什么 scala 函数中的块变量在执行内部块后无法更新?

Why a block variable in scala function could not update after executed the inner block(s)?

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

首先,该函数将为每个产品 ID 从数据库中提取一个产品,然后计算 individual sub total 并与 sub total 求和。我想要 return 计算出的小计。计算没问题,但不幸的是 return 是 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
}

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

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

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

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

异步解决方案需要以某种方式重写 calculateSubTotal,即 returns Future[Int]