gpt4 book ai didi

scala - "No default Typeable for parametrized type"使用 Shapeless 2.1.0-RC2

转载 作者:行者123 更新时间:2023-12-01 15:15:00 27 4
gpt4 key购买 nike

我试图使用 Shapeless Typeable 来使对 Java 库的访问更加类型安全,但遇到了障碍。我不确定我是否滥用了该库,是否必须手动提供类型类实例,或者是否有其他问题。

此代码演示了我的问题的简化演示。

import shapeless._
import syntax.typeable._

def gaugeOpt(name: String): Option[Gauge[Double]] = {
return registry.getGauges.get(name).cast[Gauge[Double]]
}

..使用 Shapeless-2.1.0-RC2 和 Scala 2.11.5 会导致此错误:

No default Typeable for parametrized type com.codahale.metrics.Gauge[Double]

显示的库并不重要;只是对在我的 Scala 代码中使用 Java 库时使它们更加类型安全的一般模式感兴趣。

解决方案:

根据已接受答案的建议,我编写了以下类型类实例:

implicit def gaugeTypeable[T](implicit castT: Typeable[T]): Typeable[Gauge[T]] =
new Typeable[Gauge[T]] {
def cast(t: Any): Option[Gauge[T]] = {
if(t == null) None
else if(t.isInstanceOf[Gauge[_]]) {
castT.cast(t.asInstanceOf[Gauge[_]].getValue) match {
case None => None
case _ => Some(t.asInstanceOf[Gauge[T]])
}
} else None
}
}

唯一需要注意的是,我必须访问仪表值访问器才能恢复已删除的类型。

最佳答案

对于未参数化的类型,有一个默认的 Typeable 实例,因为您可以通过检查它们的运行时类来安全地(大概)转换它们。但是由于泛型在运行时被删除,这对于参数化类型来说是不安全的; t.getClass() 可能会返回 Gauge.class,但这并不能保证 t 是一个 Gauge[Double] 而不是,比方说,Gauge[Int]

您需要手动提供一个类型类实例:

implicit def gaugeTypeable[A](implicit innerTypeable: Typeable[A]) =
new Typeable[Gauge[A]] {
def cast(t: Any): Option[Gauge[A]] = ...
//confirm whether t is really a Gauge[A]
//probably making use of innerTypeable to check the
//"inner" value
}

关于scala - "No default Typeable for parametrized type"使用 Shapeless 2.1.0-RC2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28300776/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com