Scala - 如何重构一个使用reduceLeft而不是迭代的方法?



我有Java背景,最近开始学习Scala。我已经实现了一个在我看来更像Java风格的方法。如何使用各种 Scala 功能对其进行改进,使其更像 Scala 的方法?

我有一个想法来使用这样的reduceLeft

val sales: List[Sale] = salesList.sortBy(_.timestamp)

sales.reduceLeft(someFunction)

并且该函数可能具有类似于

def reduceSalesFunction: (Sale, Sale) => Sale= {
???
}

以下是我实现该方法的方式。是否有改进的空间?

def processSales(sales: List[Sale]): Sale = {
// if just a single sale, get it
if (sales.size == 1) sales.iterator.next 
else {
// get the oldest sale
val sortedSales = sales.sortWith(_.timestamp < _.timestamp)
val oldestSale: Sale = sortedSales.min
val salesMetrics: Metrics = oldestSale.metrics
// update the oldest sale's metrics
for (sale <- sortedSales) {
val metrics: Metrics = sale.metrics
if (metrics.isMetric_1) salesMetrics.setIsMetric_1(metrics.isMetric_1)
if (metrics.isMetric_2) salesMetrics.setIsMetric_2(metrics.isMetric_2)
if (metrics.isMetric_3) salesMetrics.setIsMetric_3(metrics.isMetric_3)
}
// if there are metrics with `false` values set the oldest sale's metrics to `false` as well (Metrics is an Enum)
for (metric <- Metrics.values(); if !salesMetrics.isSet(metric)) {
salesMetrics.setMetricValue(metric, false)
}
oldestSale
}
}

我有一些风格建议给你:

  • 不要调用方法getSomthting它不是getter,我认为是 对Java也有效。
  • 您可以将if else替换为模式匹配。

例:

sales match {
// if just a single sale, get it
case x :: Nil => x
// get the oldest sale
case other    => //your logic
}
  • 希望对类型推断使用相同的模式。

选择以下选项之一:

val sortedSales: List[Sale] = sales.sortWith(_.timestamp < _.timestamp)
val oldestSale: Sale = sortedSales.min
val salesMetrics: Metrics = oldestSale.metrics

val sortedSales = sales.sortWith(_.timestamp < _.timestamp)
val oldestSale = sortedSales.min
val salesMetrics = oldestSale.metrics
  • 如果可能,请避免使用"_"作为方法/字段命名(isMetric_1(。
  • 不要使用";"。行分隔块更具可读性。

例:

for { 
metric <- Metrics.values()
if !salesMetrics.isSet(metric)
} salesMetrics.setMetricValue(metric, false)
  • 另一个好的做法是使用不可变结构。

附言:

这只是我的意见。这取决于您的团队!

我强烈建议您看看 https://docs.scala-lang.org/style/。

享受Scala!:)

最新更新