这看起来很奇怪。以下编译正常:
def foo(s: String) = "balsh"
def foo(s: String)(s2: String) = "kahsd"
如果我隐含了第二个参数,它仍然可以正常编译。
但是,以下情况不会:
def foo(s: String) = "bjda"
def foo(s: String)(fun: String => String) = fun(s)
^由于“对重载定义的模糊引用”,将无法编译。
我最初的想法是Scala将函数转换为Java的方式导致两者的签名相同。但是,看看编译编码(对于第二个函数,因为它不能用两者编译)和javap,你会看到这样的函数实际上被转换成:
public java.lang.String foo(java.lang.String, scala.Function1);
因此创建了一个具有不同签名的单独方法。那为什么这不能编译?
现在让问题更加令人困惑,以下实际上编译得很好!
def foo(s: String) = "bjda"
def foo(s: String, fun: String => String) = fun(s)
如果你把功能作为第一组参数的一部分,那么一切都很好!
有谁知道为什么会这样?
编辑:
所以我试过这个:
object main {
def write(s: String) = "sasd"
def write(s: String)(implicit s2: String => String) = s2(s)
}
我只是在隐含的第二个参数中创建了该函数。瞧,这是编译。
这是它生成的java代码:
public final class main$ extends java.lang.Object{
public static final main$ MODULE$;
public static {};
public java.lang.String write(java.lang.String);
public java.lang.String write(java.lang.String, scala.Function1);
}
这是我原本期望的,没有隐含的!
答案 0 :(得分:0)
我猜测编译器无法在两者之间进行选择,因为它们实际上只是在返回类型上有所不同。基于函数的返回类型仅调度参数是不可能的。想想这样的签名:
def foo(s: String): String
def foo(s: String): String => String
不确定为什么你让它工作如果你隐含,我得到同样的错误(如我所料)。
def foo(s: String, fun: String => String)
另一方面,有一个不同的参数列表,可以发送到。
答案 1 :(得分:0)
如果有人想避免隐含的黑客行为,这是另一种方式:
def foo(s: String) = "balsh"
def foo(t: String)(s2: String) = "kahsd"
其中第二个函数的参数名称更改为不同的名称。然后,当你想要第一个:
foo(s = "foo")
当你想要第二个时:
foo(t = "foo")