【问题标题】:How to write a generic function that takes a generic that implements a class that takes in other generics如何编写一个泛型函数,该函数采用一个泛型,该泛型实现一个采用其他泛型的类
【发布时间】:2019-08-07 20:28:27
【问题描述】:
  def recordToType[A <: TBase[T, F]](record: ConsumerRecord[String, Array[Byte]]): A = {
    (new TDeserializer(new TCompactProtocol.Factory())).deserialize(new A[T, F](), record.value())
  }

上面的语法不起作用,但基本上我希望 A 被限制为 TBase 但 TBase 需要两个类型参数。如果我将这些参数排除在外,则表示参数是必需的,如果我输入参数,则表示参数未解析...编写此代码的正确方法是什么?

【问题讨论】:

  • 只需将额外的类型参数添加到列表中:def recordToType[T, F, A &lt;: TBase[T, F]]
  • new A[T, F]() 不会编译,因为构造函数可以接受参数(无论如何它应该只是new A())。您应该考虑使用类型类来解决这个问题,并使用工厂方法来创建新实例。
  • 你能给我们一个MCVE吗?

标签: scala generics


【解决方案1】:

你可以这样写你的方法的签名:

import scala.language.higherKinds

def recordToType[T, F, A[_, _] <: TBase[T, F]](record: ConsumerRecord[String, Array[Byte]]): A[T,F]

但是您的代码还有另一个问题。你不能像这样创建一个泛型类型的新实例:

new A[T, F]

它会显示类似的错误:Error:(15, 9) class type required but A[T,F] found

虽然你不能用隐含的ClassTag 捕获A 的类:

 def recordToType[T, F, A[_, _] <: TBase[T, F]](record: ConsumerRecord[String, Array[Byte]])(
    implicit m: scala.reflect.ClassTag[A[_,_]]
  ): A[T,F] = {
   val a:A[T,F] = m.runtimeClass.getConstructors.head.newInstance().asInstanceOf[A[T, F]]
   ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    相关资源
    最近更新 更多