Scala - 使用泛型方法定义特征

时间:2016-02-29 12:11:54

标签: scala generics

如何在其方法中定义具有泛型参数的特征,然后使用特定的类型参数覆盖?

一个例子:

import shapeless._

case class UserA(name:String)
case class UserB(name:String)

trait User {
  def save(item:Option[T]): Option[T]
}
class UserAdmin extends User {
  def save(item:Option[UserA]): Option[UserA]
}
class UserSomethingElse extends User {
  def save(item:Option[UserB]): Option[UserB]
}

有了这个,我得到了错误not found: type T,即使它是在无形

中定义的

3 个答案:

答案 0 :(得分:6)

如果您沿着这些方向做某事,那就有用了:

{{1}}

答案 1 :(得分:2)

必须记住,此时T不表示typeclass,而是用作占位符。因此,可能有T无形但与占位符T无关。

以下是对Type polymorphism的一个很好的介绍:https://twitter.github.io/scala_school/type-basics.html

所以基本上@mfirry已经建议:

trait User[T] { // T is placeholder
  def save(item:Option[T]): Option[T]
}

new User[String] {
  // using override her is considered best practice
  override def save(item:Option[String]): Option[String] = item
}

答案 2 :(得分:2)

除了@ mfirry之外,另一个选择就是这样,我们使用类型成员(而不是类型参数)。

trait User {
  type T
  def save(item:Option[T]): Option[T]
}
class UserAdmin extends User {
  type T = UserA
  def save(item:Option[UserA]): Option[T]
}
class UserSomethingElse extends User {
  type T = UserB
  def save(item:Option[UserB]): Option[T]
}

在我的实际情况中,这实际上更好,因为我有几个这样的类型,其具体实现将在子类中有所不同(参数和返回参数的类型不同)。所以像这样:

trait User {
  type T
  type R
  def save(item:Option[T]): Option[R]
}
class UserAdmin extends User {
  type T = UserA
  type R = UserAA
  def save(item:Option[T]): Option[R]
}
class UserSomethingElse extends User {
  type T = UserB
  type R = UserBB
  def save(item:Option[T]): Option[R]
} 

这篇文章很有帮助:http://www.artima.com/weblogs/viewpost.jsp?thread=270195