编译此代码:
class Test {
def f(arg: Int)(defaultArg: String => Unit = println): Unit = ???
f(42)
}
失败
missing argument list for method f in class Test
[error] Unapplied methods are only converted to functions when a function type is expected.
[error] You can make this conversion explicit by writing `f _` or `f(_)(_)` instead of `f`.
[error] f(42)
[error] ^
[error] one error found
为什么会失败?它会引入歧义吗?是否可以使其无需借助单个参数列表?
答案 0 :(得分:8)
您的案例的正确语法如下:
f(42)()
您可以通过将defaultArg定义为隐式来调用f(42)工作:
def f(arg: Int)(implicit defaultArg: String => Unit = println): Unit = ???
然后你可以打电话给它:
f(42)
答案 1 :(得分:0)
因此,您将Int
参数传递给可以打印它的方法和函数。现在当你说f(42)
时,编译器会看到该函数可以应用于Int
并导致另一个函数。也就是说,这是部分应用功能的情况。
因此,当您调用f(42)
时,结果是另一个函数。因此,编译器会抱怨您应该传入第二个参数或将此结果视为部分应用的函数。
考虑以下代码,
val ptln1:String=>Unit = System.out.println _ //Doing this to show the type of the println function
def f(arg: Int)(defaultArg: String => Unit = ptln1): Unit = ???
val t = f(42)()
正如您所看到的,我明确地写了类型,所以它是有道理的 所以现在你可以使用implicits传递函数,如下所示,
def f(arg: Int)(implicit defaultArg: String => Unit = println _): Unit = ???
f(42)()
或者没有暗示,
def f(arg: Int)(defaultArg: String => Unit = println _): Unit = ???
val t = f(42)()
如果我使用自定义函数而不是println
,还可以考虑以下选项。也许这会让它更清晰。
implicit def testPrint(str:String):Unit = ???
def f(arg: Int)(implicit defaultArg: String => Unit = testPrint): Unit = ???
val t = f(42)
或者没有暗示,
def testPrint(str:String):Unit = ???
def f(arg: Int)(defaultArg: String => Unit = testPrint): Unit = ???
val t = f(42)()