【问题标题】:Scala - Acessing the type of a parameterized classScala - 访问参数化类的类型
【发布时间】:2018-09-24 21:28:29
【问题描述】:

想象一下,我有一个可以容纳某种动物的盒子。
可以给这个盒子提供原始数据,这些数据应该被转换/序列化成与盒子里已经存在的动物相同类型的动物。
换句话说,如果给一个 Box of dogs 一些“数据”,我想验证“数据”是另一只狗。

trait Animal
trait Dog extends Animal
trait Cat extends Animal   

 class Box[T<:Animal](elems: List[T]) {

      def receiveNewAnimal(data: String): T = validate[T](data)(<implicit val>)
    }

通常,当我想针对特定动物验证“rawData”时,我会这样做(例如狗):

val getMyDog(data: String): Dog = validate[Dog](data)

但是,我不知道 Box[T] 包含哪种类型的 Animal。
如果我让它保持原样:

def receiveNewAnimal(data: String): T = validate[T](data)(<implicit val>)

我收到一个编译错误,说我没有 T 类型的隐式(即使很难,我也拥有 Animal 子特征的所有可能的隐式)。
看来我无法告诉编译器,我想根据当前 Box 包含的 Animal 类型验证数据。

  1. 为什么会发生这种情况?
  2. 能否解决?如何解决?

【问题讨论】:

  • 什么是验证?而你谈论隐含 - 我看不到任何东西。
  • @user-unknown 这是我遇到的更复杂问题的模拟示例。 validate 是一个验证“json 序列化数据”并将其转换为其他数据类型的函数。它是通过隐式来实现的。每个“其他数据类型”自然必须有一个隐含的。这有帮助吗?
  • 没有。我是一个注重实用的开发人员,必须尝试一下。所以我写了我自己的验证函数,希望它和你的一样吗?你知道minimal reproducible example吗?将一些代码复制/粘贴到 REPL 中很快。复制到编辑器中,搜索正确的导入非常耗时。我有需要的 json-lib 吗?没有进口声明,我很难说。也许你可以用一个不依赖 json 的模拟类/模拟函数来组成一个例子?如果询问者提供了所有信息,则代码的 50 名阅读者每人可节省 10 分钟。通过提供minimal reproducible example,您通常会找到解决方案。

标签: scala generics types implicit-conversion scala-generics


【解决方案1】:

您必须将隐式值从调用Box 构造函数的调用点传输到validate 方法。


假设有类似下面的类型类:

trait Validatable[T]

validate 要求TValidatable

def validate[T : Validatable](serializedData: String): T = ???

你可以这样做:

trait Animal
trait Dog extends Animal
trait Cat extends Animal   

class Box[T <: Animal : Validatable](elems: List[T]) {
  def receiveNewAnimal(data: String): T = validate[T](data)
}

或者,如果您的 validate 使用第二个参数列表声明,您可以对 Box 执行相同操作:

def validate2[T](serializedData: String)(implicit v: Validatable[T]): T = ???

class Box2[T <: Animal](elems: List[T])(implicit v: Validatable[T]) {
  def receiveNewAnimal(data: String): T = validate[T](data)(v)
}

Validatable 在这种情况下实际上并不那么重要,可能是一些 ClassTag,可能是一些提供反序列化策略的宏生成令牌。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多