scala – 隐式参数解析 – 设置优先级
发布时间:2020-12-16 19:12:27 所属栏目:安全 来源:网络整理
导读:我正在尝试创建一个类型类Default,它提供给定类型的默认值.这是我到目前为止提出的: trait Default[A] { def value: A}object Default { def withValue[A](a: A) = new Default[A] { def value = a } def default[A : Default]: A = implicitly[Default[A]]
我正在尝试创建一个类型类Default,它提供给定类型的默认值.这是我到目前为止提出的:
trait Default[A] { def value: A } object Default { def withValue[A](a: A) = new Default[A] { def value = a } def default[A : Default]: A = implicitly[Default[A]].value implicit val forBoolean = withValue(false) implicit def forNumeric[A : Numeric] = withValue(implicitly[Numeric[A]].zero) implicit val forChar = withValue(' ') implicit val forString = withValue("") implicit def forOption[A] = withValue(None : Option[A]) implicit def forAnyRef[A >: Null] = withValue(null : A) } case class Person(name: String,age: Int) case class Point(x: Double,y: Double) object Point { implicit val pointDefault = Default withValue Point(0.0,0.0) } object Main { def main(args: Array[String]): Unit = { import Default.default println(default[Int]) println(default[BigDecimal]) println(default[Option[String]]) println(default[String]) println(default[Person]) println(default[Point]) } } 上述实现的行为与预期的一样,除了BigInt和BigDecimal(以及其他用户定义类型为Numeric的实例)的情况,其中它给出null而不是零.我应该怎么做才能使forNumeric优先于forAnyRef并且我得到了我期望的行为? 解决方法
选择forAnyRef隐式是因为根据Scala引用的§6.26.3“重载分辨率”,它比forNumeric更具体.有一种方法可以通过将其移动到Default扩展的特征来降低其优先级,如下所示:
trait LowerPriorityImplicits extends LowestPriorityImplicits { this: Default.type => implicit def forAnyRef[A >: Null] = withValue(null: A) } object Default extends LowerPriorityImplicits { // as before,without forAnyRef } 但这只是技巧的一部分,因为现在forAnyRef和forNumeric都是彼此特定的,你会得到一个含糊不清的隐含错误.这是为什么?好吧,forAnyRef得到一个额外的特异性点,因为它对A:A>:Null有一个非平凡的约束.那么,为了向forNumeric添加一个非平凡的约束,你可以做的是在默认值中将它加倍: implicit def forNumericVal[A <: AnyVal: Numeric] = withValue(implicitly[Numeric[A]].zero) implicit def forNumericRef[A <: AnyRef: Numeric] = withValue(implicitly[Numeric[A]].zero) 现在,这个额外的约束使得NumericVal和forNumericRef对于Numeric可用的类型的forAnyRef更具体. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |