隐式分辨率选择最具体的子类型

时间:2019-07-04 17:49:24

标签: scala implicit subtype scalac

有人可以解释一下为什么scala解析最通用的隐式而不管本地范围的隐式更具体吗?

示例:

import scala.math.ScalaNumber

type Serializer[T] = T => String

object SerializedOps{
  implicit class AnyOps[T](t: T){
    def serialize(implicit s: Serializer[T]) : String = s(t)
  }
}

object Instances{
  implicit val scalaNumber : Serializer[ScalaNumber] = _.toString + "_DEFAULT"
}


import SerializedOps._
import Instances._


implicit val bigDecimalCustom : Serializer[BigDecimal] = _.toString + "_CUSTOM"

val res: String = BigDecimal(100).serialize
//res: String = 100DEFAULT

为什么我不能在本地范围内定义更具体的新隐式? Scala如何解决隐式?

1 个答案:

答案 0 :(得分:4)

Subtype does win

  

如果有几个与隐式匹配的合格参数   参数的类型,将使用规则选择最具体的类型   静态超载分辨率。

函数contravariant在其参数类型上是

ScalaNumber => String

的子类型
BigDecimal => String

因此ScalaNumber => String更具体。请注意,type Serializer[T] = T => String为函数类型的别名。