Scala案例类伴随对象 - 类型名称冲突
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala案例类伴随对象 - 类型名称冲突相关的知识,希望对你有一定的参考价值。
我面临着Companion Objects选择其类型而不是案例类的问题
我正在使用喷雾json serdes。他们需要一个隐式的JsonFormat。这种格式是通过调用一个依赖于case类的参数个数的函数来获得的:如果case类有两个字段,就像jsonFormat2(Class2)一样
case class Class2(a: String, b: Integer)
或者jsonFormat3(Class3)
case class Class3(a: String, b: Integer, c: Long)
鉴于必须知道你的case类在整个代码中的params数量并不好,我想创建一个case类伴随对象,这样你就可以封装这个信息并从类本身获取JsonFormat,如:
object Class2 extends DefaultJsonProtocol
{
def getJsonFormat() = {
jsonFormat2(Class2)
}
}
但如果我这样做,我将得到以下编译问题:
type mismatch;
[error] found : mypackage.Class2.type
[error] required: (?, ?) => ?
[error] jsonFormat2(Class2)
如果我们查看jsonFormat2中的代码,签名是:
def jsonFormat2[P1 :JF, P2 :JF, T <: Product :ClassManifest
(construct: (P1, P2) => T): RootJsonFormat[T] = { // ...
如果我更改伴随对象名称(例如,更改为MyClass2),它将正常工作。所以,似乎类型是冲突的。
似乎在处理打字时,伴侣对象将无法像他们使用的类一样被命名。
有人可以解释为什么会发生这种情况,如果存在限制,或者如何处理它,那么伴侣对象可以使用相同的名称吗?
你对object Class2
的定义不会扩展(String, Integer) => Class2
。您可能希望明确传递apply
方法:
case class Class2(a: String, b: Integer)
object Class2 extends DefaultJsonProtocol
{
def getJsonFormat() = {
jsonFormat2(Class2.apply)
}
}
受@ AlexeyRomanov的有用评论的启发,我决定添加一个稍微更详细的解释,为什么它在你没有定义一个伴随对象时起作用,以及为什么它在你定义为object Class2 { ... }
时停止工作。
如果你编译
class Foo(n: Int, s: String)
那么自动生成的伴随对象的反编译代码如下所示:
public final class Foo$
extends AbstractFunction2<Object, String, Foo>
implements Serializable {
/* some lines omitted */
public Foo apply(int n, String s) {
return new Foo(n, s);
}
/* some lines omitted */
}
也就是说,它扩展了AbstractFunction2
,因此符合(?, ?) => ?
。
当您自己定义object Foo
时,生成的对象不会扩展(Int, String) => Foo
。这就是为什么它在你自己定义一个伴随对象而不扩展Function
时停止工作的原因。
当隐含地定义Class2
的伴随对象时,它会扩展(String, Integer) => Class2
;你的版本没有。如果你改为
object Class2 extends DefaultJsonProtocol with (String, Integer) => Class2 { ... }
它会起作用,但为了避免重复参数类型,我会选择Andrey Tyukin的建议(即使解释不正确)。
以上是关于Scala案例类伴随对象 - 类型名称冲突的主要内容,如果未能解决你的问题,请参考以下文章