是否有一个Scala等效的Python列表解包(又名"*")运算符?

Jef*_*ans 22 python scala argument-passing

在Python中,我们有星号(或"*"或"unpack")运算符,它允许我们解压缩列表以方便用于传递位置参数.例如:

range(3, 6)
args = [3, 6]
# invokes range(3, 6)
range(*args)
Run Code Online (Sandbox Code Playgroud)

在这个特定的例子中,它不会节省太多的输入,因为range只需要两个参数.但你可以想象,如果有更多的参数range,或者args是从输入源读取,从另一个函数返回等等,那么这可能会派上用场.

在Scala中,我找不到相应的东西.请考虑在Scala交互式会话中运行以下命令:

case class ThreeValues(one: String, two: String, three: String)

//works fine
val x = ThreeValues("1","2","3")

val argList = List("one","two","three")

//also works
val y = ThreeValues(argList(0), argList(1), argList(2))

//doesn't work, obviously
val z = ThreeValues(*argList)
Run Code Online (Sandbox Code Playgroud)

除了使用的方法之外,还有更简洁的方法val y吗?

Rég*_*les 27

scala中没有直接的等价物.你会发现最接近的是使用_*,它仅适用于vararg方法.例如,这是一个vararg方法的示例:

def hello( names: String*) {
  println( "Hello " + names.mkString(" and " ) )
}
Run Code Online (Sandbox Code Playgroud)

可以与任意数量的参数一起使用:

scala> hello()
Hello
scala> hello("elwood")
Hello elwood
scala> hello("elwood", "jake")
Hello elwood and jake
Run Code Online (Sandbox Code Playgroud)

现在,如果您有一个字符串列表并希望将它们传递给此方法,那么解压缩它的方法是_*:

scala> val names = List("john", "paul", "george", "ringo")
names: List[String] = List(john, paul, george, ringo)
scala> hello( names: _* )
Hello john and paul and george and ringo    
Run Code Online (Sandbox Code Playgroud)


Mil*_*bin 5

你可以使用shapeless获得一些通往 Python 的途径,

Welcome to Scala version 2.11.0-20130208-073607-ce32c1af46 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_05).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import shapeless._
import shapeless._

scala> import Traversables._
import Traversables._

scala> case class ThreeValues(one: String, two: String, three: String)
defined class ThreeValues

scala> val argList = List("one","two","three")
argList: List[String] = List(one, two, three)

scala> argList.toHList[String :: String :: String :: HNil].map(_.tupled).map(ThreeValues.tupled)
res0: Option[ThreeValues] = Some(ThreeValues(one,two,three))
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Scala 中对于 shapeless 需要更多的仪式。这是因为 Shapeless 强加了编译时约束,这些约束保证在运行时得到满足(与 python 不同,如果args大小错误或包含错误类型的元素,它将在运行时失败)...相反,您必须指定输入您期望 List 具有的类型(在本例中正好是 3 Strings),并准备好处理不满足该期望的情况(因为结果明确是 an Optionof ThreeValues)。


Jen*_*der 4

函数也有类似的东西:tupled它将一个带有 n 个参数的函数转换为一个带有一个 n 元组类型参数的函数。

请参阅此问题以获取更多信息:scala tuple unpacking

这种数组方法没有多大意义,因为它只适用于具有多个相同类型参数的函数。