2016-03-30 147 views
1

我有這樣的代碼:斯卡拉奇怪的錯誤類型

package deliveries.NewPost 
import play.api.data._ 
import play.api.data.Forms._ 

case class NewPostValidator(town: String, number: Int) 

object NewPost extends Delivery{ 
    def form[NewPostValidator](): Form[NewPostValidator] = Form(mapping(
    "town" -> nonEmptyText, 
    "number" -> number)(NewPostValidator.apply)(NewPostValidator.unapply)) 
} 

在編譯的時候它給了我奇怪的錯誤:

type mismatch; [error] found : play.api.data.Mapping[deliveries.NewPost.NewPostValidator] [error] required: play.api.data.Mapping[NewPostValidator]

基本上同一類顯示了完整的路徑和不充分路徑。 它可能是什麼?

我將闡明我想實現的目標: 我希望每個類擴展特徵都有方法「form」,它返回帶有一些驗證器的Form。爲此,我創建了以下特性:

trait Delivery { 
    def form[T](): Form[T] 
} 

並嘗試在我的課程中實現此方法。

回答

1

def form[NewPostValidator]就像是說def form[T],只是用不同的標識符。編譯器在方法主體中看不到NewPostValidator作爲「真正的」NewPostValidator,而是作爲您在def form[NewPostValidator]中聲明的構成類型NewPostValidator。

解決方案:

參數化與[T],而不是你方法的特點,並且具有類與特定類型的延伸的性狀。

trait Delivery[T] { 
    def form(): Form[T] 
} 

object NewPost extends Delivery[NewPostValidator] { 
    def form(): Form[NewPostValidator] = Form(mapping(
    "town" -> nonEmptyText, 
    "number" -> number)(NewPostValidator.apply)(NewPostValidator.unapply)) 
} 
+0

謝謝@slouc。你是對的。我想要做的是讓函數兼容特性,這個函數是def form [T]():Form [T]所以,我需要這個[NewPostValidator]部分,但不知道如何使它工作 – user2975535

+1

如果該特徵中的方法是'def form [T]():Form [T]'並且你正在擴展它(因此你需要實現方法形式),那麼這個方法需要保留相同的簽名。你所做的只是將「T」重命名爲「NewPostValidator」。如果你想「專門化」這個方法,而不是任何T,而只是NewPostValidator,那麼它就不再是同一個函數了(也就是說,如果你正在實現或重寫方法'def form [T]():Form [T]'那麼你必須使用相同的簽名;你不能只縮小它只爲NewPostValidator工作)。 – slouc

+1

嘗試通過提供更多代碼(包括該特性)來更詳細地解釋您的問題。你現在知道爲什麼你的嘗試不起作用,但我不能告訴你如何實現你想要實現的目標,因爲我沒有完整的畫面。例如,你可以做另一件事 - 如果你是這個特性的作者,把[T]從方法參數移到類參數,例如,特質Foo [T],然後讓你的類擴展Foo [NewPostValidator]。這樣方法可以分別具有簽名'def form():Form [T]'和'def form():Form [NewPostValidator]'。 – slouc