使用列表中的参数调用函数

时间:2013-09-29 13:34:59

标签: scala

有没有办法用列表中的参数调用函数? Python中的等价物是sum(*args)

// Scala

def sum(x: Int, y: Int) = x + y
val args = List(1, 4)

sum.???(args)      // equivalent to sum(1, 4)

sum(args: _*)不会在这里工作。 不管怎么说,不要改变功能的声明。我熟悉了一个重复参数def sum(args: Int*)的函数。

2 个答案:

答案 0 :(得分:2)

好吧,你可以写

sum(args(0), args(1))

但我想你希望这适用于任何列表长度?然后你会去foldreduce

args.reduce(sum)  // args must be non empty!

(0 /: args)(sum)  // aka args.foldLeft(0)(sum)

这些方法假设列表成对减少。例如,foldLeft[B](init: B)(fun: (B, A) => B): B会将A类型的元素列表缩减为B类型的单个元素。在此示例中,A = B = Int。它以初始值init开头。由于您想要求和,因此空列表的总和将为零。然后它使用当前累加器(运行总和)和列表的每个连续元素调用该函数。

所以就像

var result = 0
result = sum(result, 1)
result = sum(result, 4)
...

reduce方法假定列表非空并且要求元素类型不会更改(函数必须从两个Int映射到Int)。

答案 1 :(得分:0)

我不建议在大多数情况下使用它,因为它有点复杂且难以阅读,绕过编译时检查等。但是,如果您知道自己在做什么并且需要这样做,则可以使用反射。这应该适用于任何可变参数类型。例如,以下是使用列表中的参数调用构造函数的方法:

import scala.reflect.runtime.universe

class MyClass(
  val field1: String,
  val field2: Int,
  val field3: Double)

// Get our runtime mirror
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)

// Get the MyClass class symbol
val classSymbol = universe.typeOf[MyClass].typeSymbol.asClass

// Get a class mirror for the MyClass class
val myClassMirror = runtimeMirror.reflectClass(classSymbol)

// Get a MyClass constructor representation
val myClassCtor = universe.typeOf[MyClass].decl(universe.termNames.CONSTRUCTOR).asMethod

// Get an invokable version of the constructor
val myClassInvokableCtor = myClassMirror.reflectConstructor(myClassCtor)

val myArgs: List[Any] = List("one", 2, 3.0)

val myInstance = myClassInvokableCtor(myArgs: _*).asInstanceOf[MyClass]