【问题标题】:Implement generics in trait and method在特征和方法中实现泛型
【发布时间】:2015-11-20 03:48:26
【问题描述】:

我已经在 scala-user 论坛上发布了这个问题,

https://groups.google.com/forum/#!topic/scala-user/xlr7KmlWdWI

我收到了一个我很满意的答案。但是,与此同时,我想确定这是否是唯一的结论。谢谢

我的问题是,比如说,我有,

trait Combinable[A] {
  def join[B](l: List[A]): B
}

例如,当我用 A 作为 String 和 B 作为 Int 来实现这个 trait 时,

class CombineString extends Combinable[String] {
  override def join[Int](strings: List[String]) = string.size
}

显然,Int,在 join 方法旁边,不是 Scala 整数类,并且 编译此代码将失败。或者,我可以将我的特质重写为

trait Combinable[A, B] {
  def join(l: List[A]): B
}

trait Combinable[A] {
  def join[B](l: List[A])(f: List[A] => B): B
}

我的问题是,我怎样才能实现第一个示例中定义的特征?如果第一个例子因为它的定义方式没有实际用途,为什么编译器不抱怨呢?再次感谢。

【问题讨论】:

  • 编译器不会抱怨,因为它不知道传递给 A 和 B 的内容。开发人员必须遵守纪律。
  • 我明白,但从人类的角度来看(我和另一个回答的人)只有一个结果,抛出异常,编译器抛出警告是好的。除非有其他我不知道的结果
  • 今天的编译器中没有“实际使用”这样的术语\实体

标签: scala generics traits


【解决方案1】:

您不能期望编译器了解哪些类型组合对您有意义,但您可以将这种意义指定为多参数隐式中的类型之间的关系。

结果基本上是您拒绝的两种方法的组合,但具有所需的语法。

两种被拒绝形式中的第一种成为隐式类型:

trait Combine[A, B] {
  def apply(l: List[A]): B
}

接下来可以定义合适的类型组合及其含义

implicit object CombineStrings extends Combine[String, String] {
  def apply(l: List[String]) = l.mkString
}

implicit object CombineInts extends Combine[Int, Int] {
  def apply(l: List[Int]) = l.sum
}

implicit object CombinableIntAsString extends Combine[Int, String] {
  def apply(l: List[Int]) = l.mkString(",")
}

最后我们修改了第二个被拒绝的表单,它隐藏了 f 隐式结果的参数:

trait Combinable[A] {
  def join[B](l: List[A])(implicit combine: Combine[A, B]): B = combine(l)
}

现在你可以定义

val a = new Combinable[String] {}
val b = new Combinable[Int] {}

检查一下

a.join[String](List("a", "b", "c"))
b.join[Int](List(1, 2, 3))
b.join[String](List(1, 2, 3))

运行良好,而

a.join[Int](List("a", "b", "c"))

让编译器哭泣,直到您能够以隐式值的形式提供StringInt 之间关系的实际使用证据

【讨论】:

    【解决方案2】:

    我的问题是,如何按原样实现第一个示例中定义的特征?

    class CombineString extends Combinable[String] {
      override def join[B](strings: List[String]) = null.asInstanceOf[B]
      // or, for that matter, anything and then .asInstanceOf[B]
    }
    

    编译器怎么知道这不是你想要的?

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 1970-01-01
      • 2023-01-12
      • 2020-12-24
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多