簡體   English   中英

標記類型:類型不匹配

[英]Tagged type : type mismatch

我嘗試使用scalaz中的Tagged Type來加強類型安全性。

我遇到了一個我不明白的警告和錯誤。

你能解釋我兩個嗎?

這是控制台的輸出:

scala> sealed trait PostId
defined trait PostId

scala> def PostId(l: Long) : Long @@ PostId = Tag[Long, PostId](l)
PostId: (l: Long)scalaz.@@[Long,PostId]
warning: previously defined trait PostId is not a companion to method PostId.
Companions must be defined together; you may wish to use :paste mode for this.

scala> case class Post(id: PostId)
defined class Post

scala> Post(PostId(2l))
<console>:26: error: type mismatch;
 found   : scalaz.@@[Long,PostId]
    (which expands to)  Long with AnyRef{type Tag = PostId}
 required: PostId
              Post(PostId(2l))

在您的示例中, PostId只是一種標記類型。 實際tagg- 型(你應該操縱型)是Long @@ PostId

錯誤是你已經定義了Post來獲取PostId的實例,當你真的想讓它采用Long @@ PostId的實例時,因此類型不匹配。

我建議重命名PostIdPostIdTag和定義PostId作為別名Long @@ PostId

sealed trait PostIdTag
type PostId = Long @@ PostIdTag

def PostId(l: Long) : PostId = Tag[Long, PostIdTag](l)

然后你可以保持你的Post定義。

更新 :事實證明,scalaz標記類型似乎只適用於類型<: AnyRef ,即無法從AnyVal子類型創建標記類型。

然后解決方案是用java.lang.Long替換Long (它透明地工作,因為scala會自動將java.lang.Long值轉換為Long ):

sealed trait PostIdTag
type PostId = java.lang.Long @@ PostIdTag
def PostId(l: java.lang.Long) : PostId = Tag[java.lang.Long, PostIdTag](l)
case class Post(id: PostId)
Post(PostId(2l))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM