【发布时间】:2020-02-18 16:04:36
【问题描述】:
上下文:
我正在尝试在 RESTful 端点中使用 Jackson 提供的多态子类型 JsonSubTypes。各种请求主体之间存在一些共性,所以我有:
abstract class A extends Translatable {
val infoA: String
val infoB: String
}
case class B(
infoA: String,
infoB: String,
infoC: String,
infoD: Int
) extends A {
override type T = B
def translate(
requestInfo: String,
request: B
): String = s"<$infoA,$infoB>:$infoC-${infoD.toString}"
}
case class C(
infoA: String,
infoB: String,
infoC: Array[String]
) extends A {
override type T = C
def translate(
requestInfo: String,
request: C
): String = s"<$infoA,$infoB>:${infoC.mkString}"
}
具有以下特征,因此无需将传入的A 请求与B 或C 进行模式匹配:
trait Translatable {
type T <: A
def translate(
requestInfo: String,
request: T
): String
}
问题是当我编译它抱怨类型不匹配:
found: request.type (with underlying type com.program.A)
required: request.T
我尝试了几件事,但无济于事,只有这个似乎接近了:
- 隐式广义类型约束
e.g.,
def translate[X](
requestInfo: String,
request: X
)(implicit ev: X <:< A) = ...
(modifying the case class impl. of ^ accordingly)
但这会导致
无法证明 com.program.A <: request.t>
关于如何做到这一点的任何想法?还是我必须忍受模式匹配?我说是因为第一个代码块在我模式匹配并调用具体的 impl 时才有效。 translate 或 B 或 C,但我更愿意只使用 A 类型参数并在其上调用 translate。这可能吗?
编辑:添加上述产生编译错误的实例:
class Program {
def doWork(
info: String,
request: A
): String = {
request.translate(
info,
request // compilation fails/complains about this param in both cases
)
}
}
EDIT2:添加限定条件:我需要在子类型B 和C 中覆盖类型,以便在翻译函数中。我可以调用特定于B 或C 的字段
【问题讨论】:
-
"当我编译它抱怨类型不匹配" 编译什么?您能否更具体地说明哪条特定行会产生错误?以下代码编译没有错误:gist.github.com/DmytroMitin/eb059348c416dead20d7af7a47acfccd
-
与@DmytroMitin 的结果相同
-
抱歉,已更新示例
-
更新了上面的
B和C,带有实际的实现。的翻译来强调为什么我需要覆盖类型 T。我需要能够访问特定于子类型的字段
标签: scala inheritance types jackson abstract