gpt4 book ai didi

scala - 作为参数传递时,函数转换的隐式方法不起作用?

转载 作者:行者123 更新时间:2023-12-03 18:20:55 25 4
gpt4 key购买 nike

我可能遗漏了一些东西,但我遇到了一种令人惊讶的不起作用的模式。
这里是:

object A {
def bar(func: (Int, Int) => Int): Int = 2
def bar(func: Int => Int): Int = 3
def foo(func: Int => Int): Int = 4
}

def f(n: Int) : Int = n + 1
val g: Int => Int = f

A.foo(f) // works fine
A.bar(f) // doesn't work
A.bar(g) // but this works

编译器要求我显式应用方法 f为了通过它(写作 f _ ): Unapplied methods are only converted to functions when a function type is expected.
我不明白为什么在传递 f 时隐式进行了转换至 A.foo但当传递给 A.bar 时不会.可能与 bar有关。有两个重载,但我不知道为什么?

我在 Scala 2.12.8 中使用 scalac。

最佳答案

错误消息为您指明了正确的方向:作为一种方法,f不直接等价于 Int => Int 类型的值,尽管它们很相似。为了将其作为参数传递,f需要转换为一个值,这通常但并不总是隐式完成。

当您申报时 val g = f _ ,或使用 A.bar(f _)您显式地将方法转换为值。

因为bar方法重载,编译器不确定您正在转换哪种类型 f到(是 Int => Int 还是 (Int,Int) => Int?)。为避免任何意外,它会要求您进行显式转换。您也可以使用 A.bar(f: Int => Int) 使其编译,因为这通过显式选择 bar 之一来消除歧义。定义。

编译器可能会尝试对此进行推理,因为您正在传递 Int => Int并且隐式方法->值(value)提升只有在您打算将其提供给 bar(Int => Int) 时才会发生,但在这种情况下,它只是没有。这可能有技术原因,比如编译器没有尝试将重载解析和隐式提升结合起来,因为组合爆炸。我认为这是编译器的一个小限制,通过更明确的方式很容易规避。更明确的往往更好!

正如@slouc 在评论中所链接的,有关此问题的更多技术细节可用 here .

关于scala - 作为参数传递时,函数转换的隐式方法不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58079970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com