热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

按名称和按值类型的多态类型推断

如何解决《按名称和按值类型的多态类型推断》经验,有好办法吗?

我一直坚持使用类型推断问题而且我不确定我是否做错了,编译器中存在错误,或者它是对语言的限制

我创建了一个虚拟示例来显示问题,用例没有意义,但请相信我,我有一个有效的用例

假设我有这个代码

val function: (Int, String) => String = (_, _) => ""

implicit class Function2Ops[P1, P2, R](f: (P1, P2) => R) {
   def printArgs(p1: P1, p2: P2): Unit = println(p1, p2)
}

function.printArgs(1, "foo")

这工作和打印(1,foo) 现在,如果我更改代码(注意副名称参数)

val function: (Int, => String) => String = (_, _) => ""

implicit class Function2Ops[P1, P2, R](f: (P1, P2) => R) {
   def printArgs(p1: P1, p2: P2): Unit = println(p1, p2)
}

function.printArgs(1, "foo")

它会打印出来 (1,MyTest$$Lambda$131/192881625@61d47554)

现在,在这一点上,我可以尝试模式匹配和/或使用TypeTag来提取值,以防万一是一个名字参数,但是,我实际上想要实现的是做这样的事情

trait Formatter[T] {
  def format: String
}

case class ReverseStringFormat(v: String) extends Formatter[String] {
  override def format: String = v.reverse
}

case class PlusFortyOneFormat(v: Int) extends Formatter[Int] {
  override def format: String = (v + 41).toString
}

implicit def noOpFormatter[T](v: T): Formatter[T] = new Formatter[T] {
  override def format: String = v.toString
}

val function: (Int, => String) => String = (_, _) => ""

implicit class Function2Ops[P1, P2, R](f: (P1, P2) => R) {
   def printArgs(p1: Formatter[P1], p2: Formatter[P2]): Unit = println( p1.format, p2.format)
}

function.printArgs(1, ReverseStringFormat("foo"))

请注意,我的主要意图是我应该能够传递参数的原始类型或格式化器,这就是为什么这个扩展方法的签名使用的原因,这Formatter[TypeOfOriginalParam]也是implicit def noOpFormatter[T](v: T): Formatter[T]我不想要任何格式化的原因.

现在,在这里,我做不了多少,因为代码无法使用此错误进行编译

Error:(22, 40) type mismatch;
   found   : ReverseStringFormat
   required: Formatter[=> String]
   function.printArgs(1, ReverseStringFormat("foo"))

如果我使用隐式类的名字创建第二个类型参数,我可以使它运行

val function: (Int, => String) => String = (_, _) => ""

implicit class Function2Ops[P1, P2, R](f: (P1, => P2) => R) {
   def printArgs(p1: Formatter[P1], p2: Formatter[P2]): Unit = println( p1.format, p2.format)
}

function.printArgs(1, ReverseStringFormat("foo"))

这打印 (1,oof)

现在,主要问题是我想为任何函数执行此操作,无论其任何参数是按值还是按名称.那就是我被困住的地方,我可以为每个可能的副词组合创建不同的隐式类,其中有或不带名字参数但是它不实用,因为我需要为从Function1到Function10的每个函数执行此操作,并且by-name和by-value参数之间可能的组合数量将是巨大的.

有任何想法吗?如果我只对这种类型感兴趣,我真的需要关心论证的懒惰吗?我是否尝试做一些不受设计支持的事情,或者可能是编译器中的错误?

顺便说一句,这是我想要避免的

val function: (Int, => String) => String     = (_, _) => ""
val function2: (Int, String) => String       = (_, _) => ""
val function3: (=> Int, String) => String    = (_, _) => ""
val function4: (=> Int, => String) => String = (_, _) => ""

implicit class Function2Ops[P1, P2, R](f: (P1, => P2) => R) {
  def printArgs(p1: Formatter[P1], p2: Formatter[P2]): Unit = println("f1", p1.format, p2.format)
}

implicit class Function2Opss[P1, P2, R](f: (P1, P2) => R) {
  def printArgs(p1: Formatter[P1], p2: Formatter[P2]): Unit = println("f2", p1.format, p2.format)
}

implicit class Function2Opsss[P1, P2, R](f: (=> P1, P2) => R) {
  def printArgs(p1: Formatter[P1], p2: Formatter[P2]): Unit = println("f3", p1.format, p2.format)
}

implicit class Function2Opssss[P1, P2, R](f: (=> P1, => P2) => R) {
  def printArgs(p1: Formatter[P1], p2: Formatter[P2]): Unit = println("f4", p1.format, p2.format)
}

function.printArgs(1, "foo")
function2.printArgs(1, ReverseStringFormat("foo"))
function3.printArgs(1, "foo")
function4.printArgs(PlusFortyOneFormat(1), "foo")

它的工作原理(注意我随机使用了格式化程序或原始值,如果原始参数是按名称或按值,则无关紧要)

(f1,1,foo)
(f2,1,oof)
(f3,1,foo)
(f4,42,foo)

但是把这一切都写给我似乎有点奇怪


推荐阅读
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
author-avatar
Andiry舍甫琴科
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有