【问题标题】:Passing Scala Object/companion object as parametric type将 Scala 对象/伴随对象作为参数类型传递
【发布时间】:2017-03-23 17:29:55
【问题描述】:

我想要一个这样的方法:

def foo[O] = O(1,2,3)

其中“O”是一个定义了 apply 方法的 scala 对象。通过我的签名,我得到了“无法解析符号 O”错误。

调用 foo 传递“Set”或“List”作为参数给我“Type XXX 接受类型参数”。将伴随对象作为参数类型传递的方法是什么?

我怎样才能创建这个方法?

【问题讨论】:

  • 因为这样的声明没有任何意义。你想做什么?
  • 我知道这没有任何意义,这就是我问的原因:) 我想要这样的东西:
  • foo[Seq] = Seq(1,2,3) foo[List] = List(1,2,3) 以此类推

标签: scala generics


【解决方案1】:

将 apply 方法(当你说 List(1, 2, 3) 时调用的东西)作为参数传递:

def foo[O](apply: (Int*) => O): O = apply(1, 2, 3)

println(foo(List.apply))
->  
List(1, 2, 3)

或者,如果你真的想传入 Collection 类的伴生对象(虽然这比上面的解决方案用途更少),你可以传入 GenericCompanion 对象,例如 List 伴生对象:

def foo[O[T] <: GenTraversable[T]](comp: GenericCompanion[O]): O[Int] = comp(1, 2, 3)

println(foo(List))
->  
List(1, 2, 3)

请注意,这需要在编译器中启用更高种类的类型。

或者,您可以使用隐式 CanBuildFrom(这些是为所有集合为您定义的),而不是传入伴随对象:

def foo[O[_]](implicit bf: CanBuildFrom[O[_], Int, O[_]]): O[Int] = 
  bf().++=(Seq(1, 2, 3)).result().asInstanceOf[O[Int]]

println(foo[List])
->  
List(1, 2, 3)

【讨论】:

  • 谢谢!我想有一种方法可以只使用符号 foo[List] 但我发现这是不可能的
  • @Stefano 这实际上是可能的,看我的编辑,但它实际上仍然传递了一个(隐式)参数
  • 谢谢@Vitruvius,你太棒了:)
【解决方案2】:

伴随对象的类型使用.type 属性引用。如果你想创建一个伴随对象的列表,下面的方法会起作用:

object MyObject {
  def apply():Unit = {
    println("Hello, world")
  }
}

val c = List[MyObject.type](MyObject, MyObject)
c.foreach(_.apply())

【讨论】:

  • 我认为他们不想创建伴随对象列表。
  • 只有一个 MyObject.type 类型的对象 - 创建它的列表是没有意义的。
  • OP 专门要求“调用 foo 将“Set”或“List”作为参数传递给我“Type XXX 采用类型参数”。将伴随对象作为参数传递的方法是什么类型?”我提供了一种创建该列表或集合的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多