簡體   English   中英

隱式轉換的類型推斷

[英]Type inference of implicit conversions

考慮以下代碼:

sealed trait Data
case class StringData(string: String) extends Data
case class IntData(int: Int) extends Data

trait Reader[A] {
  def read(data: Data): A
}

implicit val stringReader: Reader[String] = {
  case StringData(string) => string
  case _                  => sys.error("not a string")
}
implicit val intReader: Reader[Int] = {
  case IntData(int) => int
  case _            => sys.error("not an int")
}

在此范圍內,我想編寫一個隱式方法,該方法將Data值靜默轉換為它們的“實際” Scala值。

implicit def fromData[A: Reader](data: Data): A =
  implicitly[Reader[A]].read(data)

但是,此代碼無法編譯:

val str: String = StringData("foo")
val int: Int = IntData(420)

錯誤是類型不匹配。 標准的隱式調試方法表明,無法fromData中的A (所有隱式Reader均顯示為適用)。

為了您的方便, 是指向該代碼的鏈接。 另一本Scastie中 ,提供了一個類似但又不同的工作片段。

我的問題:這是怎么回事?

Data類以及讀者的隱式轉換進行如下更改,可以編譯代碼。

import scala.language.implicitConversions

sealed trait Data[A]
case class StringData(string: String) extends Data[String]
case class IntData(int: Int) extends Data[Int]

trait Reader[A] {
  def read(data: Data[A]): A
}

implicit val stringReader: Reader[String] = {
  case StringData(string) => string
  case _                  => sys.error("not a string")
}
implicit val intReader: Reader[Int] = {
  case IntData(int) => int
  case _            => sys.error("not an int")
}

implicit def fromData[A](data: Data[A])(implicit ev: Reader[A]): A = ev.read(data)

val str: String = StringData("foo")
val int: Int = IntData(420)

您需要輸入數據,以便編譯器可以根據Data的類型參數推斷應使用哪個Reader。 另請注意,如果未定義隱式Reader,則以下內容將不會編譯。

case class DoubleData(d: Double) extends Data[Double]

// Fails compilation because no implicit Reader exists.
val d: Double = DoubleData(5d)

暫無
暫無

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

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