簡體   English   中英

抽象類型成員的評估

[英]evaluation of an abstract type member

為什么這段代碼不能編譯? 在 Scala 2.13.6 上測試。 有沒有辦法讓 scalac 知道SizeOfType[Unit]#Size實際上是Short

trait SizeOfType[T] {
  type Size
  def getSize(): Size
}

object SizeOfType {
  implicit def unit: SizeOfType[Unit] = new SizeOfType[Unit] {
    type Size = Short
    def getSize(): Short = 0
  }

  def test(implicit ev: SizeOfType[Unit]): Short = ev.getSize()
}
[error] type mismatch;
[error]  found   : ev.Size
[error]  required: Short
[error]   def test(implicit ev: SizeOfType[Unit]): Short = ev.getSize()

當使用類型成員而不是類型參數進行參數化時,您必須在要求類型 class 實例時提供類型細化,否則您只要求 Scala

SizeOfType[Unit]

而不是預期的

SizeOfType[Unit] { type Size = Short }

所以像

implicit val unit: SizeOfType[Unit] { type Size = Short } =
  new SizeOfType[Unit] {
    type Size = Short
    def getSize(): Short = 0
  }

def test(implicit ev: SizeOfType[Unit] { type Size = Short }): Short = ev.getSize()
val x: Short = test // ok

通常你會創建依賴類型的方法,然后你可以避免方法定義中的類型細化(但它仍然需要定義類型 class 實例)

implicit val unit: SizeOfType[Unit] { type Size = Short } = ???
def test(implicit ev: SizeOfType[Unit]): ev.Size = ev.getSize()
val x: Short = test // ok

我建議通過underscoreio/shapeless-guide的“第 4 章,使用類型和隱含”進行學習,特別是其中提到的部分

...如果我們將返回類型定義為Second[L] ,則Out類型成員將從返回類型中刪除,並且類型 class 將無法正常工作。

不,沒有辦法。

想想如果你用另一個定義type Size = IntSizeOfType[Unit]類型的隱式值調用test會發生什么。

或者換一種說法,方法test只能根據SizeOfType的 trait 定義來推斷類型,而不是根據一個實際的隱含值內容。

但是,您可以將test定義為返回類型ev.Size

暫無
暫無

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

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