在Python中,我们有星号(或“*”或“unpack”)运算符,它允许我们解压缩列表以方便用于传递位置参数。例如:
range(3, 6)
args = [3, 6]
# invokes range(3, 6)
range(*args)
在这个特定的例子中,它不会节省太多的输入,因为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)
除了val y
中使用的方法之外,还有更简洁的方法吗?
答案 0 :(得分:25)
scala中没有直接的等价物。
你会发现最接近的是_*
的用法,它仅适用于vararg方法。
例如,这是一个vararg方法的例子:
def hello( names: String*) {
println( "Hello " + names.mkString(" and " ) )
}
可以与任意数量的参数一起使用:
scala> hello()
Hello
scala> hello("elwood")
Hello elwood
scala> hello("elwood", "jake")
Hello elwood and jake
现在,如果您有一个字符串列表并希望将它们传递给此方法,那么解压缩它的方法是_*
:
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
答案 1 :(得分:4)
函数有类似的东西:tupled
它将一个带n个参数的函数转换为一个函数,该函数接受一个类型为n-tuple的参数。
有关详细信息,请参阅此问题:scala tuple unpacking
这样的数组方法没有多大意义,因为它只适用于具有相同类型的多个参数的函数。
答案 2 :(得分:4)
您可以使用shapeless,
了解PythonWelcome 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))
正如你所看到的,Scala需要更多的仪式,没有形状。这是因为无形会强制编译时限制,这些约束保证在运行时得到满足(与python不同,如果args
的大小错误或者包含错误类型的元素,它将在运行时失败)...而不是你'重新强制指定您希望List具有的类型(在这种情况下恰好是三个Strings
)并准备好处理不满足该期望的情况(因为结果显式为Option
ThreeValues
)。
答案 3 :(得分:2)
另一种解包列表的方法:
val a :: b :: c :: _ = argList
val z = ThreeValues(a, b, c)