Scala有没有办法从已经应用的函数中获取参数?

这是否有意义,应该完成或适合任何用例?

例子:

def doStuff(lower:Int,upper:Int,b:String)= for(turn <- lower to upper) println(turn +": "+b)

想象一下,在某一时刻,我知道“较低”的论点,并获得了将其应用于“ dostuff”的函数

val lowerDoStuff = doStuff(3,_:Int,_:String)

我有办法让那3个回来吗? (为了举例来说,想象一下我在一个仅接收“ LowerDostuff”的函数中,现在需要知道第一个参数)

惯用性鳞片比内省/反射(如果可能)。

有帮助吗?

解决方案

惯用性鳞片: 不,你不能。您已经明确说第一个论点不再相关。如果编译器可以使其完全消失,那最好:您说您的功能取决于INT和字符串,并且您对生成的内容没有任何承诺。如果你 真的 需要该值,但是您也确实需要通过2个题目函数,您可以手动完成:

class Function2From3[A,B,C,Z](f: (A,B,C) => Z, val _1: A) extends Function2[B,C,Z] {
  def apply(b: B, c: C) = f(_1, b, c)
}
val lowerDoStuff = new Function2From3(doStuff _, 3)

现在,当您以后获取功能时,您可以模式匹配以查看是否是function2FROM3,然后读取值:

val f: Function2[Int,String,Unit] = lowerDoStuff
f match {
  case g: Function2From3[_,_,_,_] => println("I know there's a "+g._1+" in there!")
  case _ => println("It's all Greek to me.")
}

(如果对您来说重要的是整数很重要,则可以删除 A 作为通用参数并制作 _1 成为一个整数 - 也许只是称呼它 lower 当你在那里)。

反射: 不,你不能(通常不是)。编译器比这更聪明。生成的字节码(如果我们将您的代码包装在 class FuncApp) 是:

public final void apply(int, java.lang.String);
  Signature: (ILjava/lang/String;)V
  Code:
   0:   aload_0
   1:   getfield    #18; //Field $outer:LFuncApp;
   4:   iconst_3
   5:   iload_1
   6:   aload_2
   7:   invokevirtual   #24; //Method FuncApp.doStuff:(IILjava/lang/String;)V
   10:  return

注意 iconst_3?那是您3的去处 - 它消失在字节码中。甚至没有一个隐藏的私有字段,其中包含该值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top