我正在尝试编写一个函数,根据传入的参数,它可以返回不同的类型。要使用一个非常简单的例子,这是我的目标: 给出如下对象:
case object NameToken
case object SalaryToken
case object IsDirectorToken
和
val john: Employee
然后:
以下是我想到的几种可能的实现方式。不言而喻,两者都很可怕。
可能的实施1:
trait Token[A]
case object NameToken extends Token[String]
case object SalaryToken extends Token[Int]
case object IsDirectorToken extends Token[Boolean]
case class Employee(name: String, salary: Int, isDirector: Boolean) {
def get[A](t: Token[A]): A = t match {
case NameToken => name.asInstanceOf[A]
case SalaryToken => salary.asInstanceOf[A]
case IsDirectorToken => isDirector.asInstanceOf[A]
}
}
可能的实施2:
trait Token2 {
type returnType
}
case object NameToken2 extends Token2 {
type returnType = String
}
case object SalaryToken2 extends Token2 {
type returnType = Int
}
case object IsDirectorToken2 extends Token2 {
type returnType = Boolean
}
case class Employee2(name: String, salary: Int, isDirector: Boolean) {
def get(t: Token2): t.returnType = t match {
case NameToken2 => name.asInstanceOf[t.returnType]
case SalaryToken2 => salary.asInstanceOf[t.returnType]
case IsDirectorToken2 => isDirector.asInstanceOf[t.returnType]
}
}
然而,他们两个都只是对那个演员来说很糟糕。
我可以更聪明地解决这个问题吗?
谢谢。
答案 0 :(得分:4)
class Employee(val name: String, val salary: Int, val isDirector: Boolean) {
def get[T](t: Token[T]): T = t.value(this)
}
trait Token[T] { def value(e: Employee): T }
object NameToken extends Token[String] { def value(e: Employee) = e.name }
object SalaryToken extends Token[Int] { def value(e: Employee) = e.salary }
object IsDirectorToken extends Token[Boolean] { def value(e: Employee) = e.isDirector }
<强>用法强>
scala> val john = new Employee("John", 50000, false)
john: Employee = Employee@59f99ea
scala> val name = john.get(NameToken)
name: String = John
scala> val salary = john.get(SalaryToken)
salary: Int = 50000
scala> val isDirector = john.get(IsDirectorToken)
isDirector: Boolean = false
答案 1 :(得分:1)
您可以使用重载:
case class Employee(name: String, salary: Int, isDirector: Boolean) {
def get(t: Token[String]) = name;
def get(t: Token[Int]) = salary;
def get(t: Token[Boolean]) = isDirector;
}