隐式参数解析——设置优先级

2024-04-30

我正在尝试创建一个类型类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 and BigDecimal(以及作为实例的其他用户定义类型Numeric)它给出的地方null而不是零。我应该怎么做才能forNumeric优先于forAnyRef我得到了我期望的行为?


The forAnyRef选择隐式是因为它是更具体 than forNumeric根据 Scala 参考文献的 §6.26.3“重载解析”。有一种方法可以通过将其转移到以下特征来降低其优先级: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 and forNumeric彼此一样具体,并且您会得到一个不明确的隐式错误。这是为什么?出色地,forAnyRef获得额外的特异性点,因为它对A: A >: Null。那么你可以做什么,添加一个不平凡的约束forNumeric,就是将其加倍Default:

implicit def forNumericVal[A <: AnyVal: Numeric] = withValue(implicitly[Numeric[A]].zero)

implicit def forNumericRef[A <: AnyRef: Numeric] = withValue(implicitly[Numeric[A]].zero)

现在,这个额外的约束使得forNumericVal and forNumericRef更具体地说forAnyRef对于类型,其中Numeric可用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

隐式参数解析——设置优先级 的相关文章

随机推荐

  • 当模型无效时,使用asp.net core返回到视图内的部分视图,并显示错误消息

    我有一个模态引导程序 我想显示引导模式的验证错误 但是 当我将模型留空并单击提交按钮时 它只是被视为独立页面 部分视图 model WebApplication1 Models Book
  • VB.NET:“语句 lambda 无法转换为表达式树”编译时错误

    为什么我可以执行以下操作 Dim qNodes As IQueryable Of XmlNode xDoc ChildNodes AsQueryable Dim test qNodes Where Function node True 尽管
  • Rails,单击 link_to helper 后未加载 JavaScript

    当我在 Rails 中使用 link to 帮助程序时 我在加载 javascript 时遇到了一些问题 当我手动输入 localhost 3000 products new 的 url 或重新加载页面时 JavaScript 会加载 但是
  • 在 iOS SDK 中与 Java RMI 服务器通信

    有什么方法可以在 iPhone 上构建一个能够与 Java RMI 服务器通信的客户端吗 我计划将该应用程序放在应用程序商店中 因此很高兴知道苹果是否允许通过任何方式来执行此操作 None
  • 从 JVM 线程本地空间卸载 Clojure 变量

    我正在 Clojure 中为 BaseX 编写一个插件 通过 lein uberjar 构建 并包含 Clojure 解释器 在大多数情况下 这效果很好 然而 当通过 BaseX HTTP 实例运行时 评估在 Jetty 的线程池内进行 而
  • 如何列出引用 SQL Server 中给定表的所有外键?

    我需要删除 SQL Server 数据库中高度引用的表 如何获取删除表时需要删除的所有外键约束的列表 SQL 答案比在 Management Studio 的 GUI 中单击有关更好 不知道为什么没有人建议但我使用sp fkeys查询给定表
  • NSMutableArray 销毁

    我有一个数组NSMutableArray与快乐的物体 每当我尝试清除所有对象的数组并重新填充它时 这些对象就会恶意地打开 泄漏 我 它是在 init 函数中分配的 如下所示 self list NSMutableArray array 我用
  • Chrome 浏览器自动向下滚动内容(当没有人要求时)

    我们有丰富的页面 其中有一个包含动态内容的小块 直到最近一切都运转良好 现在 Chrome 浏览器以某种方式 捕获 页面上的一个 div 并向下滚动整个内容 用语言很难解释 但演示起来却容易得多 这是测试页 只需在 Chrome 中打开它
  • 基于登录状态 React Native 的动态 DrawerNavigator

    我需要一个 DrawerNavigator 它在用户登录或注销时显示不同的选项 如下所示 未登录 sign up log in info 登录 My Account Some Actions Info Log Out
  • Python:从区间到值的映射

    我正在重构一个函数 给定一系列隐式定义间隔的端点 检查间隔中是否包含数字 然后返回相应的值 不以任何可计算的方式相关 现在处理这项工作的代码是 if p lt 100 return 0 elif p gt 100 and p lt 300
  • 使 String.CharacterView.Index 符合 Strideable:使用 stride(to:by:) 时出现致命错误:“无法增加 endIndex ”

    问题 当试图跨过去时String CharacterView Index索引 例如一步2 extension String CharacterView Index Strideable let str 01234 for in str st
  • 无法安装 MvcMailer

    我尝试通过在程序包管理器控制台中输入命令 Install Package MvcMailer 来安装 Mvc Mailer 但收到以下错误消息 Successfully installed MvcMailer 1 1 Successfull
  • 拉维尔 |如何使用多个属性执行搜索

    我正在创建属性网站 并且正在使用多个属性进行搜索 但问题是在搜索控制器中我有非常大的代码并且非常难以处理 laravel 中是否存在其他解决方案 list property Listing property where property t
  • Python:将字典转换为字节

    我正在尝试将字典转换为字节 但在将其转换为正确的格式时遇到问题 首先 我尝试使用自定义架构映射字典 模式定义如下 class User def init self name None code None self name name sel
  • RESTful API 应该有架构吗?

    最近有人告诉我 一个合适的 RESTful API 应该为其接受和返回的资源表示定义一个模式 例如 用于 XML 的 XSD 和用于 JSON 的 JSON 架构 然而 在我读过的所有关于 REST 的书籍和文章中 这一点似乎不仅没有突出
  • 将 TPopupMenu 与窗体的右侧对齐?

    TPopupMenu 如何与窗体的右侧对齐 问题是 在调用之前似乎没有办法获取弹出菜单的宽度Popup X Y Integer 我正在尝试获得与 Chrome 中的系统菜单类似的行为 你也可以只设置Alignment http docwik
  • 引导表上的滚动条

    I have table渲染在一个panel这是在一个modal 由于表格相对较大 我想将其行数限制为 5 行 以便模式不会滚动 我浏览了 SO 和谷歌 到处都看到我需要设置overflow y auto or overflow y scr
  • linq按顺序插入元素的方法

    我有一个按元素的 Name 属性排序的元素集合 我需要在保持顺序的同时将新元素插入集合中 我正在寻找一种简洁的 LINQ 方法来做到这一点 我的代码如下 this Children 是集合 d 是我需要插入的新元素 需要两次遍历集合才能找到
  • Datatables.net 与 ReactJS,在列中渲染 ReactJS 组件

    我有以下带有数据表的组件 import React Component from react import Link from react router import PanelContainer Panel PanelBody Grid
  • 隐式参数解析——设置优先级

    我正在尝试创建一个类型类Default为给定类型提供默认值 这是我到目前为止所想到的 trait Default A def value A object Default def withValue A a A new Default A