scala - 将其传递给高阶函数后,函数隐式参数不再如此

标签 scala function implicit implicits

在 Scala 中,您可以执行以下操作:

def foo(implicit v: Int) = println(v);
def h(x: Int) = { implicit val i: Int = x; foo }

h(42)
> 42
h来电获取foo引用作为闭包。

尝试通过 foo 并不奇怪至 h作为参数:
def g(x: Int)(f: Int => Unit) = { implicit val i: Int = x; f }

但它不起作用:
g(1)(foo)
> error: could not find implicit value for parameter v: Int

我认为正在发生的是 foo被调用作为对实际参数的评估。 那正确吗?

当传递带有普通参数列表(非隐式)的函数时,不会对函数求值:
def foo2(v: Int) = println("Foo2")
g(1)(foo2)
> Int => Unit = <function1>

这是预期的结果和 foo2评估不尝试作为对实际参数的评估。

为什么是 foo当没有可用的隐式值时,将其评估为实际参数?

分配也会发生同样的情况:
val fooref: Int => Unit = foo
> error: could not find implicit value for parameter v: Int

就像从 Int => UnitInt 的函数不匹配参数被标记为隐式,编译器将其作为有效的实际参数丢弃,因此尝试评估它。找不到声明的隐式值来完成调用。

如果是这样,用隐式参数表达函数类型的方式是什么?

最佳答案

不幸的是,函数不能有隐式参数——只有方法可以。

在表达式 g(1)(foo) 中, foo从方法转换为函数(也称为 eta 扩展)。和 section 6.26.2的 Scala 规范声明在 eta 扩展之前应用隐式参数。

看这张票:implicit methods behave suboptimally when used non-implicitly

关于scala - 将其传递给高阶函数后,函数隐式参数不再如此,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32716707/

相关文章:

scala - 如何读取发送到 Controller Action 中的浏览器 HTTP header ?

scala - 如何将 RX Observable 转换为 Play Enumerator

ruby - ROR 代码发送许多邮件

Perl Map block 局部变量的使用

scala - 将类型参数的上限交换为证据参数

scala - 仅当数组输入的大小为 1 时,函数才返回错误值

scala - 触发编译中未执行编译之前的 SBT 任务

javascript - 在 JavaScript 中调用和传递嵌套函数

c++将函数作为参数传递给另一个带有void指针的函数

scala - 为什么更喜欢隐式 val 而不是隐式对象