我有几个对象,我试图编写工厂方法。
简化,这些是:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
我想创建一个允许我传入类型的方法,并获取该类的实例。我想尝试这样的事情:
case class a[a1,a2](j:a1, k:a2) {}
case class b[b1,b2](j:b1, k:b2) {}
这显然不起作用(出于各种原因,包括&#T; T不能带参数'),但有没有一个优雅的解决方案来创建这样的东西?
答案 0 :(得分:7)
0 __的回答几乎就在那里。如果你使Factory[A[_,_]]
成为类型类,那么你就完成了。以下是标准化名称的示例:
// enable higher kinded types to prevent warnings
import scala.language.higherKinds
// our case classes
case class A[A1,A2](j:A1, k:A2)
case class B[B1,B2](j:B1, k:B2)
// Define our factory interface
trait Factory[T[_,_]] {
def make[P1,P2](p1: P1, p2: P2): T[P1,P2]
}
// Companion class makes factory easier to use
object Factory {
def apply[T[_, _]](implicit ev: Factory[T]) = ev
}
// Add implicit implementations of Factory[A]
implicit object AFactory extends Factory[A] {
def make[P1,P2](p1: P1, p2: P2): A[P1,P2] = A(p1, p2)
}
// Add implicit implementations of Factory[B]
implicit object BFactory extends Factory[B] {
def make[P1,P2](p1: P1, p2: P2): B[P1,P2] = B(p1, p2)
}
现在在REPL中测试工厂
scala> val a = Factory[A].make("one", 2)
a: A[String,Int] = A(one,2)
scala> val b = Factory[B].make(1, "two")
b: B[Int,String] = B(1,two)
答案 1 :(得分:2)
new
关键字cannot与类型参数一起使用,只与具体类一起使用,因为在编译时检查实例化。您可以使用reflection解决此问题。
可能更好的方法是提供特定的工厂。
E.g。
trait Factory[A[_,_]] {
def make[P, Q](p: P, q: Q): A[P, Q]
}
case class a[a1,a2](j:a1, k:a2) {}
object AFactory extends Factory[a] {
def make[P, Q](p: P, q: Q): a[P, Q] = a(p, q)
}