带有可选字段的 Scala 通用案例 class
Scala generic case class with optional field
我有以下通用案例 class 来为 HTTP API 中的资源建模(我们使用 Akka HTTP):
case class Job[Result](
id: String,
result: Option[Result] = None,
userId: String,
)
并想指定 Job
的多个命名变体,其中一些提供结果,而另一些不提供结果:
case class FooResult(data: String)
type FooJob = Job[FooResult]
// BarJob does not have any result, thus result should be None
case class BarJob = Job[/*what do to?*/]
我的问题是,有什么方法可以将 Job
定义为一般情况 class,其中仅当字段 result
为 [=17 时才需要指定类型参数=] ?我想做的是:
// result is by default None in Job, so I don't want to specify any type here
case class BarJob = Job
或者也许有更好的方法来做到这一点,而不是使用类型别名?
一种选择是将 trait
s 用于 Job
s 有和没有结果:
trait Job {
def id: String
def userId: String
}
trait JobWithResult[T] extends Job {
def result: T
}
case class FooResult(data: String)
case class FooJob(id: String, userId: String, result: FooResult) extends JobWithResult[FooResult]
case class BarJob(id: String, userId: String) extends Job
然后您可以在 Job
上使用 match
来查看它是否有结果。
job match {
case FooJob(id, userId, foo) => println(s"FooJob with result $foo")
case j: JobWithResult[_] => println(s"Other job with id ${j.id} with result")
case j: Job => println(s"Job with id {$j.id} without result")
}
这假设 result
实际上不是可选的。
正如评论中指出的那样,Option
是“不必要的”。
我提交,与其说它是“不必要的”,不如说是指示性的 ... 一种无需重复声明即可实现所需内容的方法。
case class Job[Result](id: String, userId: String, result: Option[Result] = None)
object Job {
def void(id: String, userId: String) = Job[Nothing](id, userId)
def apply[R](id: String, userId: String, result: R) = Job(id, userId, Option(result))
}
type FooJob = Job[FooResult]
type VoidJob = Job[Nothing]
我有以下通用案例 class 来为 HTTP API 中的资源建模(我们使用 Akka HTTP):
case class Job[Result](
id: String,
result: Option[Result] = None,
userId: String,
)
并想指定 Job
的多个命名变体,其中一些提供结果,而另一些不提供结果:
case class FooResult(data: String)
type FooJob = Job[FooResult]
// BarJob does not have any result, thus result should be None
case class BarJob = Job[/*what do to?*/]
我的问题是,有什么方法可以将 Job
定义为一般情况 class,其中仅当字段 result
为 [=17 时才需要指定类型参数=] ?我想做的是:
// result is by default None in Job, so I don't want to specify any type here
case class BarJob = Job
或者也许有更好的方法来做到这一点,而不是使用类型别名?
一种选择是将 trait
s 用于 Job
s 有和没有结果:
trait Job {
def id: String
def userId: String
}
trait JobWithResult[T] extends Job {
def result: T
}
case class FooResult(data: String)
case class FooJob(id: String, userId: String, result: FooResult) extends JobWithResult[FooResult]
case class BarJob(id: String, userId: String) extends Job
然后您可以在 Job
上使用 match
来查看它是否有结果。
job match {
case FooJob(id, userId, foo) => println(s"FooJob with result $foo")
case j: JobWithResult[_] => println(s"Other job with id ${j.id} with result")
case j: Job => println(s"Job with id {$j.id} without result")
}
这假设 result
实际上不是可选的。
正如评论中指出的那样,Option
是“不必要的”。
我提交,与其说它是“不必要的”,不如说是指示性的 ... 一种无需重复声明即可实现所需内容的方法。
case class Job[Result](id: String, userId: String, result: Option[Result] = None)
object Job {
def void(id: String, userId: String) = Job[Nothing](id, userId)
def apply[R](id: String, userId: String, result: R) = Job(id, userId, Option(result))
}
type FooJob = Job[FooResult]
type VoidJob = Job[Nothing]