我正在嘗試創建一個工廠模式,回傳型別是引數化的 trait,實際的回傳型別將是該 trait 的子型別,但我事先不知道泛型型別,所以我不知道如何指定回傳型別。一個簡化的版本是這樣的:
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")
這會給我和錯誤
trait Mapper 接受型別引數
但我事先不知道泛型型別。這里的方法的回傳型別應該是什么factory?
uj5u.com熱心網友回復:
好吧,您可以 return Mapper[_]... 這將編譯,但并不是很有用,正如評論中指出的那樣:您將無法以任何有意義的方式使用回傳的值,因為實際型別 ofcreate將是未知的.
如果你的映射器的不同實體總是有不同的型別引數(至少,在相同的范圍內),那么一個巧妙的解決方案是使用隱式:
object Mapper {
implicit def strMapper: Mapper[String] = new MapperA
implicit def intMapper: Mapper[Int] = new MapperB
}
然后,無論您在哪里看到這些,您都可以這樣做:
val m1: Mapper[String] = implicitly[Mapper[String]]
val m2: Mapper[Int] = implicitly[Mapper[Int]]
您也可以像這樣撰寫您的工廠函式(不過,我不確定您為什么要這樣做):
def mapperFactory[T: Mapper] = implicitly[Mapper[T]]
并像這樣使用它:
val m: Mapper[String] = mapperFactory
或者像這樣
def intMapper = mapperFactory[Int]
如果你想為同一個型別引數使用不同的映射器,它基本上是相同的想法,除了它看起來不那么整潔沒有隱式。關鍵是針對不同型別的不同工廠:
class Mapper {
def str(`type`: String): Mapper[String] = `type` match {
case "foo" => FooMapper()
case "bar" => BarMapper()
}
def int(`type`: String): Mapper[Int] = `type` match {
case "baz" => BazMapper()
case "bak" => BakMapper()
}
}
val fooMapper = Mapper.str("foo")
val bakMapper = Mapper.int("bak")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/437838.html
