Scala-Currying和默认参数

| 我有一个带有两个参数列表的函数,我试图部分应用这些函数并与curring一起使用。第二个参数列表包含所有具有默认值(但不是隐式的)的参数。像这样:
 def test(a: Int)(b: Int = 2, c: Int = 3) { println(a + \", \" + b + \", \" + c); }
现在,以下内容就可以了:
 test(1)(2, 3);
 test(1)(2);
 test(1)(c=3);
 test(1)();
现在,如果我定义:
 def partial = test(1) _;
然后可以执行以下操作:
 partial(2, 3);
有人可以解释为什么我不能在\'partial \'中省略某些/所有参数,如下所示:
 partial(2);
 partial(c=3);
 partial();
写\“ partial \”的行为本质上是否应该与\“ test(1)\”行为相同?有人可以帮我找出实现此目标的方法吗? 请帮助,我很拼命! 编辑-由于我无法在24小时内回答自己的问题,因此我将在此处发布自己的答案: 到目前为止,这是我能做的最好的事情:
class Test2(val a: Int) {
   def apply(b: Int = 2, c: Int = 3) { println(a + \", \" + b + \", \" + c); }
}

def test2(a: Int) = new Test2(a);
def partial2 = test2(1); // Note no underscore

test2(1)(2, 3);
test2(1)(2);
test2(1)(c=3);
test2(1)();

partial2(2, 3)
partial2(2);
partial2(c=3);
partial2();
这样工作...     
已邀请:
类型推论引擎将接下来的类型赋予
partial
。即eta扩展为
test(1) _
。您可以看到例如在REPL中,
partial
的类型为
(Int, Int) => Unit
,而
test
的类型为
(a: Int)(b: Int,c: Int)Unit
。 eta扩展的结果是一个
Function
对象,该对象不附带任何参数名称(因为可以使用匿名参数定义
Function
)。 要解决此问题,您必须按以下方式定义
partial
def partial(b: Int = 2, c: Int = 3) = test(1)(b,c)
也许您会想剔除values10ѭ和
partial
都能达到的默认值,以确保它们保持相等。但是我知道避免重复参数的名称而不引入额外的开销(如创建新对象等)的技巧。     
到目前为止,这是我能做的最好的事情:
class Test2(val a: Int) {
   def apply(b: Int = 2, c: Int = 3) { println(a + \", \" + b + \", \" + c); }
}

def test2(a: Int) = new Test2(a);
def partial2 = test2(1); // Note no underscore

test2(1)(2, 3);
test2(1)(2);
test2(1)(c=3);
test2(1)();

partial2(2, 3)
partial2(2);
partial2(c=3);
partial2();
这样工作...     
跟进您的评论,这是一种更紧凑的编写方式:
def test(a: Int) = new {
  def apply(b: Int = 2, c: Int = 3) {
    println(a + \", \" + b + \", \" + c)
  }
}
这比您的建议要紧凑一些,但效率较低,因为对内部
apply
的任何调用都将通过反射进行,就像结构类型一样。实际上,返回类型
test
是结构类型:
 java.lang.Object{def apply(b: Int,c: Int): Unit; def apply$default$1: 
 Int @scala.annotation.unchecked.uncheckedVariance; def apply$default$2: Int 
 @scala.annotation.unchecked.uncheckedVariance}
    

要回复问题请先登录注册