有没有办法用列表中的参数调用函数?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*)
。
有没有办法用列表中的参数调用函数?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*)
。
嗯,你可以写
sum(args(0), args(1))
但我假设您希望它适用于任何列表长度?然后你会去fold
or reduce
:
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
将 type 的元素列表减少为 typeA
的单个元素B
。在这个例子中,A = B = Int
。它从初始值开始init
。由于您要求和,因此空列表的总和为零。然后它使用当前累加器(运行总和)和列表的每个连续元素调用该函数。
所以就像
var result = 0
result = sum(result, 1)
result = sum(result, 4)
...
该reduce
方法假定列表是非空的,并且要求元素类型不改变(函数必须从两个Int
s 映射到一个Int
)。
我不推荐它用于大多数用途,因为它有点复杂且难以阅读,绕过编译时检查等,但如果你知道你在做什么并且需要这样做,你可以使用反射。这应该适用于任何任意参数类型。例如,以下是您可以使用列表中的参数调用构造函数的方式:
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]