如何为案例类创建显式伴随对象,其行为与替换编译器提供的隐式伴随对象相同?

cha*_*ium 7 scala case-class companion-object

我有一个案例类定义如下:

case class StreetSecondary(designator: String, value: Option[String])
Run Code Online (Sandbox Code Playgroud)

然后我定义一个显式的伴侣对象:

object StreetSecondary {
  //empty for now
}
Run Code Online (Sandbox Code Playgroud)

定义显式伴随对象StreetSecondary的行为导致编译器生成"隐含伴随对象"丢失; 即替换为无法访问编译器生成的版本.例如,该tupled方法可通过此隐式伴随对象在案例类StreetSecondary上使用.但是,一旦我定义了显式伴随对象,该tupled方法就会"丢失".

那么,我需要定义/添加/更改上面的StreetSecondary显式伴随对象,以重新获得所有丢失的功能,并替换编译器提供的隐式伴随对象?我想要的不仅仅是tupled恢复的方法.我想要unapply恢复所有功能(例如,包括提取器/ ).

感谢您提供的任何指导/指导.


更新1

我已经做了足够的搜索来发现几件事:

A)必须在其案例类之前定义显式伴随对象(至少在Eclipse Scala-IDE工作表中就是这种情况,并且代码在IntelliJ IDE的工作表中不起作用,无论哪个先出现).

B)有一个强制tupled工作的技术技巧(谢谢drstevens):(StreetSecondary.apply _).tupled虽然这解决了特定的tupled方法问题,但它仍然没有准确或完整地描述scala编译器在隐式伴随对象中提供的内容.

C)最后,可以定义显式伴随对象以扩展与主构造函数的参数的签名匹配的函数,并返回案例类的实例.它看起来像这样:

object StreetSecondary extends ((String, Option[String]) => StreetSecondary) {
  //empty for now
}
Run Code Online (Sandbox Code Playgroud)

同样,我仍然不能准确或完整地描述scala编译器在隐式伴随对象中提供的内容.

cha*_*ium 5

为案例类定义显式伴生对象时(从 Scala 2.11 开始),为了完全替换编译器在丢失的隐式伴生对象中提供的功能,显式伴生对象的基本模板有两个要求:

要求:
1. 必须扩展一个由元组组成的函数定义(与案例类构造函数参数的类型和顺序完全匹配),返回案例类的类型
2. 必须重写 toString 函数以提供对象类名称(相同)到相关案例类的案例)

以下是“空”显式伴随对象的原始示例代码:

object StreetSecondary {
  //empty for now
}
Run Code Online (Sandbox Code Playgroud)

这是实现上述要求后的示例代码:

object StreetSecondary extends ((String, Option[String]) => StreetSecondary) {
    //replace the toString implementation coming from the inherited class (FunctionN)
    override def toString =
      getClass.getName.split("""\$""").reverse.dropWhile(x => {val char = x.take(1).head; !((char == '_') || char.isLetter)}).head
}
Run Code Online (Sandbox Code Playgroud)

为了满足上述要求 1,extends ((String, Option[String]) => StreetSecondary)将 插入到对象名称之后、第一个大括号之前。

为了满足上述要求2,override def toString = getClass.getName.split("""\$""").reverse.dropWhile(x => {val char = x.take(1).head; !((char == '_') || char.isLetter)}).head插入到对象的主体中(显式实现仍然有问题)

非常感谢 @drstevens,他发布了 javap 输出,帮助我获得信心,上述两个步骤就是恢复丢失的功能所需的全部步骤。

  • 我不确定所有的样板是否值得找回丢失的东西。重要的函数“unapply”、“apply”、“equals”、“hashCode”、“toString”不会丢失。根据奥德斯基对您发现的问题的回答(http://stackoverflow.com/questions/3049368/why-do-case-class-companion-objects-extend-functionn),它仅因遗留原因而存在。伪专用的“tuple”函数很不错,但再说一次,它无论如何都是属于 Function2 的函数。不过,我确实从这次练习中学到了一些东西。在我写 Scala 的 3 年里,我从来没有遇到过这个。 (3认同)