将Scala对象/伴随对象作为参数类型传递

时间:2017-03-23 17:29:55

标签: scala generics

我想要一个像这样的方法:

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

其中“O”是具有已定义的apply方法的scala对象。凭借我的签名,我得到了“无法解析符号O ”错误。

调用foo传递“Set”或“List”作为参数,可以得到“ Type XXX take type parameter ”。将伴随对象作为参数类型传递的方式是什么?

如何创建此方法?

2 个答案:

答案 0 :(得分:4)

将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)

答案 1 :(得分:-1)

使用.type属性引用伴随对象的类型。如果要创建伴随对象列表,可以使用以下命令:

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

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