2015-12-08 31 views
1

我有關鍵和身體案例類。假設這些按鍵延伸Key特質,身體延伸Body特質。對於每個鍵,都有一個給定的身體類型。下面,我試圖用編譯器可以爲我檢查這個方法來編程它,它似乎工作!我可以在scala中更改編譯器給出的錯誤信息嗎?

trait Key [T <: Body] 
trait Body 

case class Body1() extends Body 
case class Body2() extends Body 

case class Key1() extends Key[Body1] 
case class Key2() extends Key[Body2] 

object Tester { 
    def func[T <: Body](key: Key[T], body: T) = { 
    println("Key: "+ key, "Body: "+body) 
    } 

    val k1 = Key1() 
    val b1 = Body1() 
    val b2 = Body2() 
    func(k1, b1) // good match 
    func(k1, b2) // wrong match 
} 

正如我想,最後一行給出了編譯時錯誤(見下文)。但是,我可以使它更具可讀性,以便我的圖書館用戶能夠理解發生了什麼?尤其是,最後的「提示」在我的情況下是誤導性的。

Error:(18, 9) type mismatch; 
found : A$A60.this.Key1 
required: A$A60.this.Key[Product with Serializable with A$A60.this.Body] 
Note: A$A60.this.Body1 <: Product with Serializable with A$A60.this.Body (and A$A60.this.Key1 <: A$A60.this.Key[A$A60.this.Body1]), but trait Key is invariant in type T. 
You may wish to define T as +T instead. (SLS 4.5) 
    func(k1, b2) 
    ^

回答

1

使用implicitNotFound可以改變編譯味精

import scala.annotation.implicitNotFound 

trait Key[T <: Body]  
trait Body 

case class Body1() extends Body  
case class Body2() extends Body 

case class Key1() extends Key[Body1]  
case class Key2() extends Key[Body2] 

@implicitNotFound("Expected ${From}, but found ${To}.") 
class CompileMsg[From, To] 

object CompileMsg { 
    implicit def implValue[T] = new CompileMsg[T, T] 
} 

object Tester { 
    def func[KeyBody <: Body, BodyBody <: Body] 
    (key: Key[KeyBody], body: BodyBody) 
    (implicit msg: CompileMsg[KeyBody, BodyBody]) = { 
    println("Key: " + key, "Body: " + body) 
    } 

    val k1: Key1 = Key1() 
    val b1  = Body1() 
    val b2: Body2 = Body2() 
    func(k1, b1) // good match 
    func(k1, b2) // wrong match 
} 

現在,爲您提供了以下錯誤信息:

Error:(35, 8) keyBody is A$A57.this.Body1 != A$A57.this.Body2 
func(k1, b2) // wrong match 
^ 
+0

很好的解決方案!我想這是否可以簡化,但我想不是。我們可以擺脫「A $ A57.This」嗎? – Mahdi

+0

如果只使用'implicitNotFound',我也沒有辦法擺脫它,但如果使用宏我們可以;但宏很難學:http://docs.scala-lang.org/overviews/macros/usecases.html –

相關問題