在 GitHub 上编辑此页面

参数解包

假设您有一个对列表

val xs: List[(Int, Int)]

并且您想将 xs 映射到一个 Int 列表,以便每对数字都映射到它们的总和。以前,执行此操作的最佳方法是使用模式匹配分解

xs map {
  case (x, y) => x + y
}

虽然正确,但这也很不方便且令人困惑,因为 case 表明模式匹配可能会失败。作为更短、更清晰的替代方案,Scala 3 现在允许

xs.map {
  (x, y) => x + y
}

或者,等效地

xs.map(_ + _)

def combine(i: Int, j: Int) = i + j
xs.map(combine)

通常,如果预期类型为 ((T_1, ..., T_n)) => U,则具有 n > 1 个参数的函数值将包装在函数类型中。元组参数被分解,其元素直接传递给底层函数。

更具体地说,适应应用于不匹配的形式参数列表。特别是,适应不是函数类型之间的转换。这就是为什么以下内容不被接受的原因

val combiner: (Int, Int) => Int = _ + _
xs.map(combiner)     // Type Mismatch

函数值必须显式元组化,而不是参数解元组化

xs.map(combiner.tupled)

虽然强烈不鼓励,但为了获得相同的效果,可以在用户代码中提供隐式转换

import scala.language.implicitConversions

transparent inline given `fallback untupling`: Conversion[(Int, Int) => Int, ((Int, Int)) => Int] = _.tupled

xs.map(combiner)

在应用转换之前尝试进行参数解包,这样范围内转换就不会破坏解包。

参考

更多信息请参见

本文