带有上下文约束的类型类内含物。

问题描述 投票:0回答:1

我正在慢慢自学Scala类型的类。假设我有下面这个例子。

object Example extends App {

  trait Serializer[T] {
    def serialize(seq: Seq[T]): String
  }

  object Serializer {
    def serialize[T](seq: Seq[T])(implicit serializer: Serializer[T]): Value = serializer.serialize(seq)
  }

  implicit object StringSerializer extends Serializer[String] {
    def serialize(seq: Seq[String]): String = seq.toString()
  }

  implicit object IntSerializer extends Serializer[Int] {
    def serialize(seq: Seq[Int]): String = seq.toString()
  }

  case class Data[T: Serializer](x: Seq[T], y: Seq[T], z: Seq[T]) {
    val series = Data.createString(x, y, z)
  }

  object Data {
    def createString[T : Serializer](x: Seq[T], y: Seq[T], z: Seq[T]) = {
      val serialize = implicitly[Serializer[T]]
      List(serialize.serialize(x), serialize.serialize(y))
    }
  }

  val x = Seq("a", "b", "c")
  val y = Seq(1, 2, 3, 4)
  val z = Seq(10, 20, 30)
  val data = Data(x, y, z)
  println(data.series)
}

现在这个失败了

找不到类型为 Example.Serializer[Any]的证据参数的隐含值 [错误] val data = Data(x, y, z)

谁能指导一下我如何能让 createString 方法可行吗?据我了解,因为我有一个 Seq[Int] 和a Seq[String]种类 [T] 将被推断为 [Any],这就导致了这个问题。

然而,我把基于我的上下文绑定的 Serializer 类型类,我想这将使编译器寻找一个 StringInt 序列器,但它没有做到这一点。基本上,我想传入我有定义的序列器的任何序列,所以在这里,任何组合的 Seq[Int]Seq[String].

如果有任何指导,将非常感激!

scala generics types implicit-conversion typeclass
1个回答
2
投票

如果你想要的字段是 Data 将要 Seq不同类型的元素,然后这样做

case class Data[T: Serializer, T1: Serializer, T2: Serializer](x: Seq[T], y: Seq[T1], z: Seq[T2]) {
  val series = Data.createString(x, y, z)
}

object Data {
  def createString[T : Serializer, T1 : Serializer, T2 : Serializer](x: Seq[T], y: Seq[T1], z: Seq[T2]) = {
    val serialize = implicitly[Serializer[T]]
    val serialize1 = implicitly[Serializer[T1]]
    val serialize2 = implicitly[Serializer[T2]]
    List(serialize.serialize(x), serialize1.serialize(y), serialize2.serialize(z))
  }
}

2
投票

同样的问题是,你想要不同的类型,但你使用的是单一类型参数。T所以编译器会推断出任何一个。也许你想这样定义你的类。

final case class Data[A: Serializer, B: Serializer, C: Serializer](x: Seq[A], y: Seq[B], z: Seq[C])

这样你就可以有三种不同的类型


另外,我建议你使用 列表矢量ArraySeq, 即具体集合,而不是 抽象 序列.

© www.soinside.com 2019 - 2024. All rights reserved.