2015-01-07 22 views
0

我正在使用scala 2.10。我對scala還是(非常)新的,我不能理解爲什麼我不能訪問print方法trait Printer[T]中的Person案例類的name字段。伴隨物體的通用性狀

這是示例代碼: 它打印出 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 
} 
+2

'p'是不受約束的'T',不'Person'。你沒有說'T'有'名字'。 –

+0

我怎麼能說這是一個人在這種情況下? – Akash

+1

將'print'方法放入'PersonPrinter'中。 – sjrd

回答

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)) 
} 

這樣,你把在具體類型實現了可打印的特點,只能創建打印機的實現。

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) 
    } 
}