【问题标题】:What exactly does 'is more specific than' mean in the context of implicits?在隐含的上下文中,“比更具体”到底是什么意思?
【发布时间】:2021-12-26 04:38:17
【问题描述】:

因此,隐式优先级基于两个因素:一个是关于声明本身具有优先级的范围(范围 A 扩展范围/特征 B,或范围 A 是从具有范围 B 的类型扩展的类型的伴生对象它的伴生对象)。另一个简单地提到 declaration Adeclaration B 更具体。现在,当我第一次阅读它时,我想到了几种可能的解释,特别是考虑到隐式方法和类型参数的潜在参数(隐式和非隐式)。经验似乎告诉我,这意味着声明 A 的返回值的类型,毕竟类型推断/tapply,是声明 B 的返回类型的子类型。所以,这很好:

  class A
  class B extends A
  implicit val A = new A
  implicit val B = new B
  implicitly[A]

那为什么不编译呢?

    implicit class A(val toInt :Int) {
        def ! = (1 /: (2 to toInt))(_ * _)
    }
    implicit class B(i :Int) extends A(i)
    1.!

什么时候做?

    class A(val toInt :Int) {
        def ! = (1 /: (2 to toInt))(_ * _)
    }
    class B(i :Int) extends A(i)

    implicit val A = { i :Int => new A(i) }
    implicit val B = { i :Int => new B(i) }
    1.!

这是“编译器以神秘方式工作”的另一种情况吗?

【问题讨论】:

    标签: scala implicit-conversion implicit


    【解决方案1】:

    基于SIP-13 - IMPLICIT CLASSES 提议您的声明:

    implicit class A(val toInt :Int) {
        def ! = (1 /: (2 to toInt))(_ * _)
    }
    

    将被转换为:

    class A(toInt: Int) {
     ...
    }
    implicit final def A(toInt: Int): A = new A(toInt);
    

    而您的B 又将转换为:

    class B(i: Int) extends A(i) {
     ...
    }
    implicit final def B(i: Int): B = new B(i);
    

    因此,您基本上是在声明 2 个具有相同参数但不明确的隐式转换方法。虽然由于已经提到隐式参数解析的“最具体”规则,最后一个并不模棱两可。

    【讨论】:

    • 恐怕我不明白为什么最后一个不是模棱两可的。一个隐式方法被具体化为一个隐式函数(在 Scala 2 中),所以我看不出语义上的区别到底在哪里。此外,如果我将隐式类声明放在单独的上下文中,然后导入它们(因此它们是本地语法上下文中可用的 borh 标识符,没有前缀),失败的示例有效:stackoverflow.com/questions/69966645/…
    • @Turin “恐怕我不明白为什么最后一个不是模棱两可的。” - 这是根据你在问题中提到的规则(分辨率隐式参数)。第一个类似于根据参数类型选择方法重载。另请参阅this 问题的答案,那里提到了您的解决方法..
    猜你喜欢
    • 2013-10-12
    • 2012-11-04
    • 2013-12-03
    • 2015-11-28
    • 2015-05-29
    • 2016-06-12
    • 1970-01-01
    • 2017-08-07
    • 2017-07-20
    相关资源
    最近更新 更多