2016-07-31 44 views
1

我在我的項目中有代表ID的對象。scala value class multiple inheritance

假設它是ChairId,TableId,LampId。我希望他們都從GenericId繼承。我希望能夠致電def f(x: GenericId) = x.id

我希望他們只持有單一的id: String,所以我想讓他們擴展AnyVal。

此外,我想爲每種類型提供功能generate這將產生我具體的ID即我想喜歡的類型的東西ChairId.generate()

我鍵入了:

sealed abstract class GenericId(val id: String) 
final case class ChairId(override val id: String) extends GenericId(id) 
final case class TableId(override val id: String) extends GenericId(id 

我但如果GenericId會從AnyVal繼承,但目前爲止沒有運氣; /我也嘗試使GenericId成爲一個特性,並使案例類擴展AnyVal與GenericId,但也不會編譯:/

Anot她的事TableId.generate()我可以提供功能generate伴侶對象,基本上解決了我的問題,但我想知道是否有可能解決,而無需定義伴侶對象? (即通過某種方式implicits)

//編輯

有關評論提供的代碼不編譯(我想):

sealed abstract class AbstractId(val id: String) extends AnyVal 
final case class CatId(override val id: String) extends AbstractId(id) 
final case class DogId(override val id: String) extends AbstractId(id) 
+0

我不完全確定你在問什麼。如果存在多個問題,您可能希望將它們分成多個Stack Overflow問題。 –

+0

請包括您嘗試過的代碼和編譯錯誤。我認爲這會有所幫助。 –

回答

3

值類不能對這種工作方式幾個原因。

首先,從documentation開始,值類別不能被任何其他類別擴展,所以AbstractId不能延伸AnyVal。 (Limitation #7

scala> abstract class AbstractId(val id: String) extends AnyVal 
<console>:10: error: `abstract' modifier cannot be used with value classes 
     abstract class AbstractId(val id: String) extends AnyVal 
        ^

其次,即使你讓AbstractId一個特點,並定義其他IDS是這樣的:

final case class DogId(val id: String) extends AnyVal with AbstractId 

..值類的用法不適合你情況,因爲類本身仍然會被分配。看到allocation summary

  1. 的值類是作爲另一種類型的處理:當

    值類實際上實例化。

  2. 一個值類被分配給一個數組。
  3. 進行運行時類型測試,如模式匹配。
+0

你打了我幾秒鐘:) – pedrofurla

1

value classes SIP有可能澄清你的疑慮的一些話:

值類...

  1. ...只能有恰好與一個公開,VAL 參數,其類型不是值類的主要構造。

  2. ...不能被另一個類擴展。

作爲每1.它不能是抽象;每2.您的編碼不起作用。

還有一個警告:

值類只能延伸普遍的特徵和不能擴展 本身。通用性狀是擴展Any的一個特徵,只是將其作爲成員,並且不進行初始化。通用特徵允許值類的方法的基本繼承,但它們產生分配的開銷 。

與所有考慮到這一點,根據你過去的片段,這可能工作:

sealed trait AbstractId extends Any { def id: String } 
final case class CatId(id: String) extends AnyVal with AbstractId 
final case class DogId(id: String) extends AnyVal with AbstractId 

但是要記住分配唯一的,如果你想使用CATID和DogId作爲AbstractId發生。爲了更好的理解,我推薦閱讀SIP。