首页 > 解决方案 > Scala:方法值不符合类型界限

问题描述

我正在尝试编写一个保存类型变量值的代码。这是示例代码:

class MethodTypeTest
{
    trait TSM[T <: TSM[T]]
    {
        def fit(): FiM[T]
    }

    trait FiM[T <: TSM[_]]
    {
        val fitErrors = mutable.HashMap[String, Double]()
    }

    class TS
    {
        //*** Here I am saving the value of the variable after some computation.
        var bestModel: Option[FiM[_]] = None
    }

    // Now define for SMA
    class SMAM extends FiM[SMA]
    {
        fitErrors("RMSE") = 10
    }
    class SMA extends TSM[SMA]
    {
        override def fit() = new SMAM()
    }
    // Now define for DMA
    class DMAM extends FiM[DMA]
    {
        fitErrors("RMSE") = 10.5
    }
    class DMA extends TSM[DMA]
    {
        override def fit() = new DMAM()
    }

    def main(args: Array[String]): Unit =
    {
        val ts = new TS
        val sma = new SMA
        val dma = new DMA
        val fms: Array[FiM[_]] = Array[FiM[_]](sma.fit(), dma.fit())
        val bestModel: FiM[_] = fms.minBy(m => m.fitErrors("RMSE"))
        // ******** Error in below line ******
        // Error:(48, 24) type arguments [_$3] do not conform to trait FiM's type parameter bounds [T <: MethodTypeTest.this.TSM[_]]
        //        ts.bestModel = Some(bestModel)
        ts.bestModel = Some(bestModel)
    }
}

看起来编译器抱怨最后一行的类型绑定太开放了。var bestModel: Option[FiM[_]] = None在定义 class 时,我有意在 statement 中保持 bestModel 的类型处于打开状态TS,因为该值稍后将计算到 FiM 之一。我如何/在哪里可以指定类型绑定以便它工作?

标签: scalatypes

解决方案


通过在有类型注释的任何地方添加类型边界,我能够编译(使用 Scala 2.13.4 的 scastie)_ <: TSM[_]FiM[_]

class TS {
    var bestModel: Option[FiM[_ <: TSM[_]]] = None
}
//...

val fms: Array[FiM[_ <: TSM[_]]] = Array(sma.fit(), dma.fit())
val bestModel: FiM[_ <: TSM[_]] = fms.minBy(m => m.fitErrors("RMSE"))

我认为这是必要的,因为否则它认为TSM[_]数组的未知类型参数必须与 val 的类型参数匹配,因此指定它也应该是通配符可以避免这种情况。


推荐阅读