Скажем, у меня есть класс М, что классы A, B, C унаследуют:Scala - возвращение того же типа, как передается в качестве аргумента
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
по существу делает то же для каждого подтипа и отличается только тем, как создается объект результата.
У меня есть подозрение, что это невозможно, и мне нужно либо скопировать код, либо создать отдельные методы преобразования, либо прибегнуть к приведению типов. Или есть лучший способ?
EDIT
Обратите внимание, что def transform[T<:M](t:T):T
не работает. Если мы попытаемся вернуть A, B или C, мы получим сообщения об ошибках ниже.
Выражение типа А, не соответствует ожидаемому типу Т
Выражение типа B не соответствует ожидаемому типу Т
Выражение типа C не соответствует ожидаемому типу Т
EDIT 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]
, который я хотел бы устранить.
Хорошее дополнение, но User1291 сказал, что мое решение не работает для него. Любая идея? –
Интересно ... в чем преимущество этого, просто перегружая метод преобразования? – User1291
@ Dimitry yes, если вы создаете свой собственный A/B/C, тогда вам нужен шаблон типа types, как я предложил, и это должно сработать. @ User1291 Преимущество состоит в том, что это можно использовать, если метод, который вызывает 'transform', сам по себе является общим (вы просто включаете ограничение типа typeclass [T: Transformer]'). – lmm