【问题标题】:Scala type inference of implicitly resolved anonymous functions隐式解析匿名函数的Scala类型推断
【发布时间】:2016-07-12 15:01:18
【问题描述】:

在尝试掌握 Scala 隐式时,我遇到了这个类型推断问题:

object Demo extends App {

  def demo(f: (Int, Int) => Int) = ???

  demo((a: Int) => 42)
  demo((a) => 42) // <-- any tricks to make this compile?

  implicit def f1Tof2(f: Int => Int): (Int, Int) => Int =
    (a: Int, b: Int) => f.apply(a)

}

编译器无法正确推断类型的原因是什么?有什么技巧可以让它发挥作用?

【问题讨论】:

  • 确保还包括相关消息。
  • 好点!编译错误是“缺少参数类型”。
  • 在我的例子中编译器说:wrong number of parameters: expected 2.Compiler 不知道(a) 的类型是Int(因为它没有指定),所以它不能隐式应用。
  • 如果 a 是泛型类型,那么您需要创建一个泛型 f1Tof12 方法

标签: scala types type-conversion


【解决方案1】:

这是不可能的。当您调用demo((a, b) =&gt; a + b)(例如)时,编译器已经期待(Int, Int) =&gt; Int,因此它会将(a, b) =&gt; a + b 推断为(Int, Int) =&gt; Int,因为它具有正确的形状。

但是,当您调用 demo(a =&gt; 42) 时,编译器会将 Function1[?, Int] 视为参数,而不会指示参数类型是什么。因为demo 需要Function2,所以编译的唯一方法是编译器可以找到从传递的参数类型到(Int, Int) =&gt; Int 的隐式转换。但它不能,因为它不知道它从 转换的类型。它不能只是假设它会是Int =&gt; Int

只有两种方法可以做到这一点。

1.) 显式声明匿名函数的参数类型,就像您已经做过的那样。这是可以应用隐式转换的唯一方法。

demo((a: Int) => 42)

2.) 为接受Int =&gt; Intdemo 提供重载。

def demo(f: (Int, Int) => Int): Int = f(1, 2)
def demo(f: Int => Int): Int = demo((a, b) => f(a))

scala> demo(a => 42)
res3: Int = 42

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    • 2014-05-22
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多