默认通用值

时间:2011-12-28 18:46:24

标签: generics scala

说我有课:

class SomeClass[+A <: AnyRef, +B <: Any]

要指定它,我总是要指定通用参数的类型。即要将其最通用的版本指定为方法参数类型,我必须执行def someMethod(param1: SomeClass[AnyRef, Any])new SomeClass[AnyRef, Any]来实例化它。当涉及到具有复杂泛型的更复杂类型时,它成为一个主要的痛苦。

当我不提供通用信息时,有没有办法让[AnyRef, Any]部分隐含?例如def someMethod(param1: SomeClass)

_有没有办法帮助我解决这个问题以及如何解决这个问题?

P.S。我为最初没有明确说明问题而道歉。

4 个答案:

答案 0 :(得分:7)

正如我的评论中所建议的那样,做这样的事情可以节省一些打字并且非常简单:

type SomeClassAny = SomeClass[AnyRef, Any]

答案 1 :(得分:5)

如果你没有真正关心关于这个东西会有什么类型,你可以用[_,_]进行参数化。示例可能是

之类的内容
val thing = new SomeClass[_, _]()

def thingDoer(sc: SomeClass[_, _]) { /* Stuff */ }

为了更清楚它的本质,下划线被称为“存在类型”,它基本上相当于Java中的原始类型,它也可以起到类似于Java中的通配符类型的作用。例如,这个精神分裂的Java代码

public void thingThatTakesAMapList(List<? extends Map> mapList) { /* Whatever */ }

与此Scala代码相同

def thingThatTakesAMapList(mapList: List[_ <: Map[_, _]]) { /* Some incredibly wild subroutine */ }

另外,值得注意的是List [Any]和List [_]之间的区别是......非常微妙。也就是说前者是Any的列表,而后者是[我不知道/关心]的列表。 _ 与Any完全不同。例如,如果您有一个具有此签名的类

class SillyClass[T <: Map[_, _]]

这样做无效

val thing = new SillyClass[Any]()

虽然可以对您有效

val thing = new SillyClass[HashMap[_, _]]()

并且,如果函数将SillyClass作为参数,则可以编写

def sillyClassTaker(sc: SillyClass[_])

并且确定sc 将在Any类型上进行参数化;它是在Map [_,_]的一些未知子类上进行参数化的。也就是说,下划线是占位符,但它仍然要求在其位置存在有效的类型参数。所以,虽然这一切都很酷,而且......我并不特别推荐使用它太多了。如果你需要做一些事情......通配符,或者根本不关心类型参数,那么这是一个很好的选择。

答案 2 :(得分:3)

这个怎么样?

scala> :paste
// Entering paste mode (ctrl-D to finish)

class SomeClass[+A <: AnyRef]

object SomeClass {
  def apply() = new SomeClass[AnyRef]
}

// Exiting paste mode, now interpreting.

defined class SomeClass
defined module SomeClass

scala> SomeClass()
res47: SomeClass[AnyRef] = SomeClass@4f63b5

修改

我认为你需要类似默认参数的东西,但是在类型级别。不幸的是,Scala没有任何此类功能。您可以使用@hyhnhjl建议的类型别名。那对我来说似乎是最好的选择。

答案 3 :(得分:1)

通常可以从构造函数参数的类型推断出,但如果构造函数不接受任何参数,则必须明确指定类型。当然,正如missingfaktor指出的那样,你总是可以为它编写一个方法来为你节省一些打字。