Избегание явного делегирования при использовании имплицитов для реализации признака
Я использую несколько таких классов:
class MyClassOne {
doSomething(a : A) : B
...
}
class MyClassTwo {
doSomething(a : A) : B
...
}
Источник для классов не находится под моим контролем. Хотя классы имеют методы с той же сигнатурой, они не реализуют интерфейс. Я хотел бы определить методы, которые работают на всех классах.
Итак, я сделал такую черту:
trait MyTrait {
doSomething(a : A) : B
}
И произвели неявные преобразования для всех классов:
implicit class MyClassOneMyTrait(myClassOne : MyClassOne) {
def doSomething(a : A) = myClassOne.doSomething(a)
}
Есть ли способ воспользоваться преимуществами соглашений об именовании, используемых в классах, и избежать явное делегирование объектов, переданных в конструктор? В более общем плане, является ли использование признака с неявными классами лучшим подходом к этой проблеме?
1 ответ:
На самом деле, есть функция scala именно для вашей ситуации. Это называетсяструктурные типы .
Для структурных типов требования к типу выражаются структурой интерфейса вместо конкретного типа. Внутренняя реализация использует рефлексию, поэтому будьте внимательны к производительности!type A = String type B = String class MyClassOne { def doSomething(a: A): B = { println("1") "1" } } class MyClassTwo { def doSomething(a: A): B = { println("2") "2" } } type MyClassType = { def doSomething(a: A): B } List[MyClassType](new MyClassOne, new MyClassTwo).foreach(_.doSomething("test")) List(new MyClassOne, new MyClassTwo).foreach { case a: MyClassType => a.doSomething("test") case _ => }