如何在 scala 中返回通用特征的子类型?
我正在尝试创建一个工厂模式,返回类型是一个参数化特征,实际返回类型将是该特征的子类型,但我事先不知道泛型类型,所以我不知道如何指定返回类型。简化版本是这样的:
trait Mapper[T] {
def createMap(a: T, b: T): T
}
class MapperA extends Mapper[String]{
override def createMap(a: String, b: String): String = {
a + b
}
}
class MapperB extends Mapper[Int]{
override def createMap(a: Int, b: Int): Int = {
a + b + b + b
}
}
def factory(typeOfMapper: String): Mapper = {
typeOfMapper match {
case "mapperA" => new MapperA()
case "mapperB" => new MapperB()
}
}
val mapper = factory("mapperA")
这会给我和错误
特征映射器采用类型参数
,但我事先不知道泛型类型。这里的工厂方法的返回类型应该是什么?
I am trying to create a factory pattern, and the return type is a parametrized trait, and the actual return type will be a subtype of that trait, but I do not know the generic type beforehand, so I don't know how to specify the return type. A simplified version is like this:
trait Mapper[T] {
def createMap(a: T, b: T): T
}
class MapperA extends Mapper[String]{
override def createMap(a: String, b: String): String = {
a + b
}
}
class MapperB extends Mapper[Int]{
override def createMap(a: Int, b: Int): Int = {
a + b + b + b
}
}
def factory(typeOfMapper: String): Mapper = {
typeOfMapper match {
case "mapperA" => new MapperA()
case "mapperB" => new MapperB()
}
}
val mapper = factory("mapperA")
This will give me and error of
trait Mapper takes type parameters
but I do not know the generic type beforehand. What should the return type be for the factory
method here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,您可以返回
Mapper[_]
...这将编译,但并不是非常有用,正如评论中指出的:您将无法在任何有意义的方式,因为create
的实际类型将是未知的。如果映射器的不同实例始终具有不同的类型参数(至少在同一范围内),那么一个巧妙的解决方案是使用隐式:
然后在任何可见的地方,您都可以这样做:
您还可以编写工厂函数(不过,我不确定你为什么想要)像这样:
并像这样使用它:
或者像这样
如果你想要相同类型参数的不同映射器,它基本上是相同的想法,除了它看起来不像整洁无隐含。关键是不同类型的工厂不同:
Well, you could return
Mapper[_]
... that will compile, but isn't really very useful, as pointed out in the comments: you won't be able to use the returned value in any meaningful way, because actual type ofcreate
will be unknown.If different instances of your mapper will always have different type parameters (at least, within the same scope), then a neat solution would be using implicits:
Then everywhere you have these visible, you can just do:
You could also write your factory function (though, I am not sure why you'd want to) like this:
and use it like this:
or like this
If you want different mappers for the same type parameter, it's basically the same idea, except it does't look as neat without implicits. The key is different factories for different types: