Scala-返回与作为参数传递的类型相同的类型
假设我有一个类M,它由类a、B、C继承:Scala-返回与作为参数传递的类型相同的类型,scala,generics,code-reuse,return-type,generic-variance,Scala,Generics,Code Reuse,Return Type,Generic Variance,假设我有一个类M,它由类a、B、C继承: abstract M A extends M B extends M C extends M 我想这样做: val a0:A = ... val b0:B = ... val c0:C = ... val a1:A = transform[A](a0) val b1:B = transform[B](b0) val c1:C = transform[C](c0) 其中,transform对每个子类型的作用基本相同,只是在结果对象的构造方式上有所不同
abstract M
A extends M
B extends M
C extends M
我想这样做:
val a0:A = ...
val b0:B = ...
val c0:C = ...
val a1:A = transform[A](a0)
val b1:B = transform[B](b0)
val c1:C = transform[C](c0)
其中,transform
对每个子类型的作用基本相同,只是在结果对象的构造方式上有所不同
我有一种不可能的预感,我需要复制代码并创建单独的转换方法,或者求助于类型转换。还是有更好的办法
编辑
请注意,def transform[T这非常简单:
class M
class A extends M
class B extends M
def transform[T <: M](obj: T): T = {
obj
}
val a0:A = new A
val a1:A = transform(a0)
val b0:B = new B
val b1:B = transform(b0)
M类
A类扩展了M
B类扩展了M类
def transform[T它取决于transform
的实现。如果编译器清楚地知道transform
保留了类型,那么@Dimitry的答案是有效的
如果您需要类型之间不太明显的(对编译器而言)关系,那么通常的方法是类型类模式
trait Transformer[T] {
def transform(t: T) : T
}
def transform[T: Transformer](t: T) = implicitly[Transformer[T]].transform(t)
implicit object ATransformer extends Transformer[A] {
def transform(a: A): A = ...
}
implicit object BTransformer extends Transformer[B] {
def transform(b: B): B = ...
}
然后,您可以在特定对象中实现A
/B
/C
的特定转换,并且编译器只允许您在隐式作用域中具有合适的转换器的情况下调用transform
。也许我撞到了头,但t>:M
意味着t是一个超类of M-M的任何超类-这在继承层次结构中是一种错误的方向?抱歉,打印错误。编辑了我的答案,试试这个代码。在我问这个问题之前,我已经试过了。不幸的是,这似乎不起作用(请参阅问题的编辑)。我已经试过了。如果它对您有效,那么我猜我与M匹配(请参阅上面的第二次编辑)根本不“明显”用@Imm的话来说,这足够让编译器在我的情况下工作了。很好的补充,但User1291告诉我,我的解决方案对他不起作用。有什么想法吗?很有趣……这比简单地重载转换方法有什么好处?@Dimitry是的,如果你正在构建自己的A/B/C,那么你需要像我一样的类型类模式建议这样做。@User1291优点是,如果调用transform
的方法本身是泛型的(您只需包含typeclass约束[T:Transformer]
),就可以使用这种方法。
class M
class A extends M
class B extends M
def transform[T <: M](obj: T): T = {
obj
}
val a0:A = new A
val a1:A = transform(a0)
val b0:B = new B
val b1:B = transform(b0)
trait Transformer[T] {
def transform(t: T) : T
}
def transform[T: Transformer](t: T) = implicitly[Transformer[T]].transform(t)
implicit object ATransformer extends Transformer[A] {
def transform(a: A): A = ...
}
implicit object BTransformer extends Transformer[B] {
def transform(b: B): B = ...
}