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)
你可以使用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 Option
of ThreeValues
)。
函数也有类似的东西:tupled
它将一个带有 n 个参数的函数转换为一个带有一个 n 元组类型参数的函数。
请参阅此问题以获取更多信息:scala tuple unpacking
这种数组方法没有多大意义,因为它只适用于具有多个相同类型参数的函数。