2016-02-29 56 views
0

如何在其方法中使用泛型參數定義特徵,然後使用特定類型參數進行重寫?Scala - 使用通用方法定義特徵

一個例子:

import shapeless._ 

case class UserA(name:String) 
case class UserB(name:String) 

trait User { 
    def save(item:Option[T]): Option[T] 
} 
class UserAdmin extends User { 
    def save(item:Option[UserA]): Option[UserA] 
} 
class UserSomethingElse extends User { 
    def save(item:Option[UserB]): Option[UserB] 
} 

有了這個,我得到的錯誤not found: type T即使它在無形

+0

我認爲你可能是混亂的「泛型編程」(這是無形約)與「參數多態性」,這似乎是什麼你在這個問題上很關心。我知道這是令人困惑的,因爲「泛型」是一個有時用於討論參數多態的術語。 –

+0

是的,你肯定是正確的..感謝您指出 – Sofia

回答

6

定義它的工作原理,如果你沿着這些路線的東西:

trait User[T] { 
    def save(item:Option[T]): Option[T] 
} 
class UserAdmin extends User[UserA] { 
    def save(item: Option[UserA]): Option[UserA] = ??? 
} 
... 
2

一必須記住,此時T並不表示typeclass,而是用作佔位符。所以它可能是沒有形狀的T,但它與佔位符T沒有關係。

這是一個很好的介紹Type polymorphismhttps://twitter.github.io/scala_school/type-basics.html

所以基本上爲@mfirry已經建議:

trait User[T] { // T is placeholder 
    def save(item:Option[T]): Option[T] 
} 

new User[String] { 
    // using override her is considered best practice 
    override def save(item:Option[String]): Option[String] = item 
} 
+0

是的,我肯定與T佔位符混淆無形。這篇文章也幫助http://www.artima.com/weblogs/viewpost.jsp?thread=270195 – Sofia

2

另一種選擇,除了@ mfirry的是這樣的,在這裏我們使用一種類型的成員,而不是(與類型參數)。

trait User { 
    type T 
    def save(item:Option[T]): Option[T] 
} 
class UserAdmin extends User { 
    type T = UserA 
    def save(item:Option[UserA]): Option[T] 
} 
class UserSomethingElse extends User { 
    type T = UserB 
    def save(item:Option[UserB]): Option[T] 
} 

在我的現實情況下,這實際上是更好,因爲我有幾個這樣的類型,其具體的實現將在子類(不同類型的參數和返回參數)不等。因此,像這樣:

trait User { 
    type T 
    type R 
    def save(item:Option[T]): Option[R] 
} 
class UserAdmin extends User { 
    type T = UserA 
    type R = UserAA 
    def save(item:Option[T]): Option[R] 
} 
class UserSomethingElse extends User { 
    type T = UserB 
    type R = UserBB 
    def save(item:Option[T]): Option[R] 
} 

這篇文章是有幫助的:http://www.artima.com/weblogs/viewpost.jsp?thread=270195