伴随对象的通用特征

时间:2015-01-07 02:52:16

标签: scala generics traits

我正在使用scala 2.10。我仍然(非常)不熟悉scala,我无法理解为什么我无法在name Person print方法中访问trait Printer[T]案例类的 Person(Mark) Person(Will)字段。

这是示例代码: 它打印出来 // Model abstract class BaseModel[T] { def all: List[T] } case class Person(name: String) object Person extends BaseModel[Person] { val people = Set(Person("Mark"), Person("Will")) def all = people.toList.sortBy(_.name) } // Controller trait Printer[T] { val model: BaseModel[T] def print = model.all.foreach { p => // p.name gives error "value name is not a member of type parameter T" println(p) } } object PersonPrinter extends Printer[Person] { val model = Person } // Call object MyApp extends App { PersonPrinter.print }

{{1}}

2 个答案:

答案 0 :(得分:2)

如果你对T没有任何限制,也就是说,对它有一些要求,你就不能知道'你可以调用任何特定的方法(除了toString,hashCode,equals以及所有对象上存在的更多方法)。

你可以这样做的一种方法是不使用像你一样的泛型,而是具体:

trait Printable {
  def text: String
}
trait Printer {
  def model: BaseModel[Printable]
  def print = model.all.foreach(p => println(p.text))
}

或者您可以使用T的类型绑定表达对T允许的要求:

trait Printer[T <: Printable] {
  def model: BaseModel[T]
  def print = model.all.foreach(p => println(p.text))
}

这样你只能创建Printer的实现,你输入的具体类型实现了Printable特性。

答案 1 :(得分:0)

我想这会编译:

trait Printer[T<:Person] {
  val model: BaseModel[T]
  def print = model.all.foreach { p =>
    // p.name gives error "value name is not a member of type parameter T"        
    println(p.name)
  }
}

或使用结构类型:

trait Printer[T<: {val name:String}] {
  val model: BaseModel[T]
  def print = model.all.foreach { p =>
    // p.name gives error "value name is not a member of type parameter T"        
    println(p.name)
  }
}