简体   繁体   English

在隐式上下文中,“比”更具体是什么意思?

[英]What exactly does 'is more specific than' mean in the context of implicits?

So, implicit precedence is based on two factors: one is about the scope of declaration itself having precedence (scope A extending scope/trait B, or scope A being a companion object of a type extended from a type with scope B as its companion object).因此,隐式优先级基于两个因素:一个是关于声明本身具有优先级的范围(范围 A 扩展范围/特征 B,或范围 A 是从以范围 B 作为其伴随对象的类型扩展的类型的伴随对象)。 The other simply mentions that declaration A is more specific than declaration B .另一个只是提到声明 A声明 B更具体。 Now, when reading it for the first time I had several possible interpretations in mind, especially considering potential parameters (implicit and not) of implicit method and type parameters.现在,当我第一次阅读它时,我想到了几种可能的解释,尤其是考虑到隐式方法和类型参数的潜在参数(隐式和非隐式)。 Experience seemed to teach me that it means that the type of the returned value by declaration A, after all type inference/ tapply , is a subtype of the return type of declaration B. So, this is fine:经验似乎告诉我,这意味着声明 A 的返回值的类型,毕竟类型推断/ tapply ,是声明 B 的返回类型的子类型。所以,这很好:

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

Why this doesn't compile, then?为什么这不能编译呢?

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

When this does?这是什么时候?

    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.!

Is it another case of 'the compiler works in mysterious ways'?这是“编译器以神秘方式工作”的另一种情况吗?

Based on SIP-13 - IMPLICIT CLASSES proposal your declaration:基于SIP-13 - IMPLICIT CLASSES提案您的声明:

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

Will be transformed to将转化为

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

And your B in its turn will be transformed to something like:而你的B反过来会变成这样的:

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

So you are basically declaring 2 implicit conversion methods with the same parameters which are ambiguous.所以你基本上是在声明 2 个具有相同参数的隐式转换方法,这些方法是不明确的。 While the last one is not ambiguous due to already mentioned "most specific" rule for implicit parameters resolution.由于已经提到的隐式参数解析的“最具体”规则,最后一个并不含糊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM