2011-12-28 89 views
6

说我有一个类:默认通用值

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

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

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

难道_可以帮我解决这个问题吗?

P.S.我很抱歉没有清楚地说明问题。

+1

如果要保存一些打字后,你可能会想尝试一个类型别名,比如'型SomeClassAny = SomeClass [AnyRef,Any]'。 – huynhjl 2011-12-28 20:05:58

+0

一个默认的'value'(见你问题的标题)是不同的:'Foobar(b:Int = 42)';你在谈论类型参数。 – 2011-12-28 20:42:18

+0

@huynhjl似乎'type'是最合适的解决方案。你应该将其作为回答发布 – 2011-12-28 21:30:06

回答

7

如我的评论所说,做这样的事情可以节省一些打字,是非常简单的:

type SomeClassAny = SomeClass[AnyRef, Any] 
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] = [email protected] 

编辑:

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

+0

请重新考虑我的问题 - 我做了一些更正。我很抱歉,最初没有说清楚。 – 2011-12-28 19:53:35

1

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

+0

请重新考虑我的问题 - 我做了一些更正。我很抱歉,最初没有说清楚。 – 2011-12-28 19:53:19

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的列表,后者是[我不知道/关心]的列表。尽管如此,_ 完全不同。例如,如果你有一类与此签名

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

它不会是有效的做到这一点

val thing = new SillyClass[Any]() 

同时可能有效期为你做这个

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

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

def sillyClassTaker(sc: SillyClass[_]) 

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

+1

感谢您的解释。但是List [_ <:Map [_,_]]和List [Map [_,_]]之间的实际区别是什么?和'List [_]'和'List [Any]'之间? – 2011-12-28 21:34:08

+0

我已编辑我的帖子来解决您的问题。 – Destin 2011-12-28 21:47:19