我只是在scala中嘗試一下,我寫了這段代碼
object Main:
def main(args: Array[String]): Unit =
val dInt: Data[Int] = IntData(1)
val dString: Data[String] = StringData("hello")
val Data(deconstructedInt) = dInt // unapply
val Data(deconstructedString) = dString // unapply
println(deconstructedInt)
println(deconstructedString)
sealed trait Data[ T]:
def get: T
case class IntData(get: Int) extends Data[Int]
case class StringData(get: String) extends Data[String]
object Data:
def apply[T](input: T): Data[T] = input match {
case i: Int => IntData(i) //compile error here
case s: String => StringData(s) //compile error here
}
def unapply[T](d: Data[T]): Option[String] = d match {
case IntData(get) => Some(s"int data => get = $get")
case StringData(get) => Some(s"string data => get = $get")
}
我在代碼中注釋的位置得到了這個錯誤
Found: IntData
Required: Data[T]
case i: Int => IntData(i)
為什么我收到此錯誤,不是IntData(或StringData)的子類Data嗎?
uj5u.com熱心網友回復:
IntData是 的子型別Data[Int]。所以 if Tis not不是的Int子型別。現在,您可能會說,如果匹配第一種情況,那么顯然是. 但是編譯器并不聰明地意識到這一點!IntDataData[T]inputTInt
您可以嘗試使用 Scala 3 的新匹配型別:
type DataOf[T] = T match {
case Int => IntData
case String => StringData
}
def apply[T](input: T): DataOf[T] = input match {
case i: Int => IntData(i)
case s: String => StringData(s)
}
另一種選擇是聯合型別:
def apply(input: Int | String): Data[Int | String] = input match {
case i: Int => IntData(i)
case s: String => StringData(s)
}
但是,這樣做會丟失型別資訊。使用匹配型別解決方案,apply(42)推斷有 type IntData。使用聯合型別解決方案,推斷有 type Data[Int | String]。
uj5u.com熱心網友回復:
這種方式編譯器連接Ts 之間的點并且它可以作業:
object Main:
def main(args: Array[String]): Unit =
val dInt: Data[Int] = IntData(1)
val dString: Data[String] = StringData("hello")
val Data(deconstructedInt) = dInt // unapply
val Data(deconstructedString) = dString // unapply
println(deconstructedInt)
println(deconstructedString)
sealed trait Data[ T]:
def get: T
case class IntData[T <: Int](get: T) extends Data[T]
case class StringData[T <: String](get: T) extends Data[T]
object Data:
def apply[T](input: T): Data[T] = input match {
case i: Int => IntData(i)
case s: String => StringData(s)
}
def unapply[T](d: Data[T]): Option[String] = d match {
case IntData(get) => Some(s"int data => get = $get")
case StringData(get) => Some(s"string data => get = $get")
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/455955.html
