说我有课:
class SomeClass[+A <: AnyRef, +B <: Any]
要指定它,我总是要指定通用参数的类型。即要将其最通用的版本指定为方法参数类型,我必须执行def someMethod(param1: SomeClass[AnyRef, Any])
或new SomeClass[AnyRef, Any]
来实例化它。当涉及到具有复杂泛型的更复杂类型时,它成为一个主要的痛苦。
当我不提供通用信息时,有没有办法让[AnyRef, Any]
部分隐含?例如def someMethod(param1: SomeClass)
?
_
有没有办法帮助我解决这个问题以及如何解决这个问题?
P.S。我为最初没有明确说明问题而道歉。
答案 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指出的那样,你总是可以为它编写一个方法来为你节省一些打字。