【问题标题】:implicit parameters and generic types隐式参数和泛型类型
【发布时间】:2015-11-28 17:28:32
【问题描述】:

我试图了解编译器在这种情况下的行为

object ImplicitTest extends App {

  def foo[T](implicit x: (String => T)): T = ???

  implicit val bar = (x: String) => x.toInt

  foo
}

上面的代码无法编译并给出以下错误:

不明确的隐含值:对象 Predef 中的两个方法 $conforms 在类型为 ⇒ String ⇒ 的对象 ImplicitTest 中键入 [A]⇒ <: bar int string t>

正如错误所说,我的隐式值与 Predef 中定义的另一个隐式冲突...基于此,似乎无法将隐式参数声明给将值从已知类型转换为未知类型的函数(通用) 类型。

这是由于编译器的一些技术限制,还是只是它应该工作的方式,并且我违反了一些我不知道的限制?

【问题讨论】:

    标签: scala implicit-parameters


    【解决方案1】:

    当您调用 foo 时,您没有向它提供类型参数(并且没有其他方法可以推断它,原因如下),因此编译器无法找到正确的和正确的隐含的。

    您在范围内有隐式bar: String =&gt; Int,但您Predef 中有隐式,它们创建=:=&lt;:&lt; 的实例,它们都扩展A =&gt; B,并创建隐式String =&gt; As。编译器正在为foo 寻找some 隐式函数String =&gt; T,但不确定是哪一个,并且您有多个范围。 bar 不会优先,因为您尚未指定它要查找的特定 String =&gt; T

    这将起作用:

    def foo[T](implicit x: (String => T)): T = ???
    
    implicit val bar = (x: String) => x.toInt
    
    foo[Int]
    

    【讨论】:

    • 知道了,所以它是关于类型推断的。现在我认为它很有意义,编译器没有足够的信息来将泛型 T 缩小为具体类型,因此“bar”会优先...感谢您的回答,现在一切都说得通了:)
    猜你喜欢
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    • 2011-08-29
    相关资源
    最近更新 更多