簡體   English   中英

使用 classOf Scala 鍵入不匹配的泛型

[英]Type mismatch generics with classOf Scala

我有一種方法可以根據配置標志format將字段成員動態轉換為特定類型。

此標志format接受以下類型值之一:

object Types {
    val Str = "string"
    val IntNum1 = "int"
    val IntNum2 = "integer"
    val DoubleNum = "double"
    val LongNum = "long"
}

一種選擇是使用反射。 另一種選擇是使用模式匹配(我正在嘗試使用的方法)

下面是String類型的方法:

private def getValClassIfStr(format: String): Class[String] = {
    format.toLowerCase match {
        case Types.Str => classOf[String]
        case _ => null
    }
}

這是從AnyVal擴展的數字類型的方法,它無法編譯:

private def getValueClass[T <: AnyVal](format: String): Try[Class[T]] = {
    format.toLowerCase match {
        case Types.IntNum1 || Types.IntNum2 => Success(classOf[Int])
        case Types.DoubleNum => Success(classOf[Double])
        case Types.LongNum => Success(classOf[Long])
        case _ => Failure(new Exception)
    }
}

由於以下原因,第二種方法無法編譯: Type mismatch: required Try[Class[T]] found Try[Class[Int]]

我不明白,給定T <: AnyVal

任何的想法? 如果這是一個糟糕的方法,那么“干凈”的替代方案是什么?

我認為一旦你用Class[AnyVal]替換返回值中的Class[T] ,為什么這不起作用的原因變得更加清晰:

type mismatch;
 found   : Class[Int](classOf[scala.Int])
 required: Class[AnyVal]
Note: Int <: AnyVal, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: AnyVal`. (SLS 3.2.10)

換句話說,任何對getValueClass[T]調用總是必須由編譯T = AnyVal填充,因為format只在運行時進行評估。 但是,這是不可能的,因為Class[T]是不變的,因此您不能將Class[Int]Class[Double]作為Class[AnyVal] ,因為對於不變容器,沒有子類型關系。

展示:

var x: Class[AnyVal] = _
x = classOf[Int]
// Boom

暫無
暫無

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

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