2014-01-23 52 views
2

比方說,我有這樣的代碼和平:重寫類型使用「類型」的關鍵字和路徑依賴的類型

trait Holder { 
    type Value 
    def put(v:Value) 
} 

class JsonHolder extends Holder { 
    override type Value = String 
    def put(v: JsonHolder.this.Value): Unit = {} 
} 

class XmlHolder extends Holder { 
    override type Value = String 
    def put(v: XmlHolder.this.Value): Unit = {} 
} 

object Foo { 
    def main(args: Array[String]) { 
    val jsonHolder = new JsonHolder 
    val xmlHodler = new XmlHolder 
    val valueOfJson = new jsonHolder.Value("AAA") 
    val valueOfXml = new xmlHodler.Value("AAA") 
    jsonHolder.put(valueOfXml) 
    } 
} 

我不明白爲什麼這個編譯。不應該由類型錯誤jsonHolder.put(valueOfXml)?

如果我改變

type Value 

到這樣的事情:

case class Value(content:String) 

,取下覆蓋線和其他一切保持原樣是類型不匹配錯誤將實際顯示。

那麼這兩者之間有什麼區別,因爲放置參數的聲明不必改變,行爲完全不同?

回答

5

那麼,這不是一個類型錯誤,因爲JsonHolder.ValueXmlHolder.Value都是String s。考慮其他類型的別名type。所有類型都將替換爲其實際類型。所以,你的代碼大致是這樣的:

val valueOfJson = new String("AAA") // JsonHolder.Value is a String 
val valueOfXml = new String("AAA") // XmlHolder.Value is a String as well 

而且這樣的:

class JsonHolder extends Holder { 
    def put(v: String): Unit = {} 
} 

class XmlHolder extends Holder { 
    def put(v: String): Unit = {} 
} 

如果你的類型之一將是,例如,一個Int那麼肯定你會得到一個編譯錯誤:

class JsonHolder extends Holder { 
    override type Value = Int 
    def put(v: JsonHolder.this.Value): Unit = {} 
} 

class XmlHolder extends Holder { 
    override type Value = String 
    def put(v: XmlHolder.this.Value): Unit = {} 
} 

object Foo { 
    def main(args: Array[String]) { 
    val jsonHolder = new JsonHolder 
    val xmlHodler = new XmlHolder 
    //compilation error here - Int doesn't have a String constructor 
    val valueOfJson = new jsonHolder.Value("AAA") 
    val valueOfXml = new xmlHodler.Value("AAA") 
    jsonHolder.put(valueOfXml) 
    } 
} 
+0

好吧,'type'在編譯過程中的行爲就像一個簡單的字符串替換,並且所有的事件只是替換,並且那裏沒有「智能」。 所以有可能這樣做: 而不是'case class Value'將其更改爲'abstract class Value',然後在其他兩個類中重寫它,以便可以修改'Value'類的某些行爲? – almendar

+0

你能否描述一下你想用這個做什麼?我想到的第一件事是參數化 - Holder [T]',和像JsonHolder這樣的類擴展了Holder [String]'。但我想你已經考慮過這個,它可能不適合你的情況 – serejja

+0

其實這並非如此,我有任何問題。我只是在玩我能做的和不能做的路徑依賴類型。 – almendar