Scala - 返回与作为参数传递的类型相同的类型
Scala - returning same type as passed as argument
假设我有一个 class M,class 是 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
对每个子类型的作用基本相同,只是结果对象的构造方式不同。
我有一种不可能的预感,我需要复制代码并创建单独的转换方法或求助于类型转换。或者有更好的方法吗?
编辑
请注意,def transform[T<:M](t:T):T
不起作用。如果我们尝试 return A、B 或 C,我们将收到以下错误消息。
Expression of type A does not conform to expected type T
Expression of type B does not conform to expected type T
Expression of type C does not conform to expected type T
编辑 2
也许关于我正在尝试做的事情的一些更详细的信息:
transform(m:M) = {
val P = Property P computed from m
m match {
case a:A => construct and return new A from a with property P
case b:B => construct and return new B from b with property P
case c:C => construct and return new C from c with property P
case _ => error
}
}
如果我那样做,那么我需要转换:
val a1:A = transform(a0).asInstanceOf[A]
val b1:B = transform(b0).asInstanceOf[B]
val c1:C = transform(c0).asInstanceOf[C]
我想删除它。
这很简单:
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)
这取决于 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
如果你在隐式范围内有一个合适的Transformer
。
假设我有一个 class M,class 是 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
对每个子类型的作用基本相同,只是结果对象的构造方式不同。
我有一种不可能的预感,我需要复制代码并创建单独的转换方法或求助于类型转换。或者有更好的方法吗?
编辑
请注意,def transform[T<:M](t:T):T
不起作用。如果我们尝试 return A、B 或 C,我们将收到以下错误消息。
Expression of type A does not conform to expected type T
Expression of type B does not conform to expected type T
Expression of type C does not conform to expected type T
编辑 2 也许关于我正在尝试做的事情的一些更详细的信息:
transform(m:M) = {
val P = Property P computed from m
m match {
case a:A => construct and return new A from a with property P
case b:B => construct and return new B from b with property P
case c:C => construct and return new C from c with property P
case _ => error
}
}
如果我那样做,那么我需要转换:
val a1:A = transform(a0).asInstanceOf[A]
val b1:B = transform(b0).asInstanceOf[B]
val c1:C = transform(c0).asInstanceOf[C]
我想删除它。
这很简单:
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)
这取决于 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
如果你在隐式范围内有一个合适的Transformer
。