Предположим, у меня есть несколько автоматически сгенерированных классов, таких как MyEnum1
, MyEnum2
, ... (они не обязательно являются типами перечисления Scala, только некоторые автоматически сгенерированные классы). Хотя тип MyEnum1
отличается от типа MyEnum2
(и они не имеют автоматически сгенерированных родительских типов, кроме Any
), я могу гарантировать, что все эти автоматически сгенерированные типы имеют абсолютно одинаковые public, static доступные методы, в частности findById
и findByName
, которые позволяют искать значение перечисления на основе индекса или имени строки.
Я пытаюсь создать функцию, которая будет использовать специфичную для типа версию findById
и findByName
, но в общем случае принимает любой из MyEnum1
, MyEnum2
, ... в качестве параметра функции.
Обратите внимание, что типичный шаблон sealed trait
+ case class
для создания типа суммы из различных перечислений здесь не поможет, потому что я говорю о распределении различных статических методов, основанных на параметре типа, и никогда не существует параметр фактического значения задействован вообще.
Например, предположим, что MyEnum1
кодирует мужской / женский пол. Так что MyEnum1.findById(0)
возвращает MyEnum1.Female
, который имеет тип MyEnum1
. И скажем, MyEnum2
кодирует цвет глаз, так что MyEnum2.findById(0)
возвращает MyEnum2.Green
, который имеет тип MyEnum2
.
Мне дана Карта, ключом которой является тип , а значением является индекс для поиска, например
val typeMap = Map(
MyEnum1 -> 0,
MyEnum2 -> 0
)
и я хотел бы сделать это в общем:
for ( (elemType, idx) <- typeMap ) yield elemType.findById(v)
|---------------|
the goal is to
avoid boilerplate
of defining this
with different
pattern matching
for every enum.
и получить некоторый тип последовательности (может иметь тип элемента Any
), который выглядит как
MyEnum1.Female, MyEnum2.Green, ...
Некоторое время я боролся с шаблоном sealed trait
+ case class
, и, похоже, концептуально это не правильный путь. Неважно, если я оберну значения из MyEnum1
или MyEnum2
в конструкторы значений класса дела, такие как FromMyEnum1(e: MyEnum1)
, и попытаюсь определить последствия для работы с этим значением , это не помогите в моем примере кода выше, когда я хочу сделать elemType.findById(...)
, потому что компилятор все еще говорит, что тип Any
(что он разрешает для типа ключа в моем Map
), не имеет метода findById
.
Я бы настоятельно предпочел не заключать сами типы в шаблон класса case, чтобы он служил в качестве ключей, но я мог бы это сделать - за исключением того, что я не могу понять, как можно трактовать сам тип как значение первого класса в конструктор класса case, наивно похожий на
case class FromMyEnum1(e: MyEnum1.getClass) extends EnumTrait
(так, чтобы ключи Map
могли иметь тип EnumTrait
и, возможно, могло быть какое-то неявное выражение, которое соответствовало бы каждому конструктору класса дел с правильной реализацией findById
или findByName
).
Любая помощь в понимании того, как Scala позволяет использовать сами типы в качестве значений внутри конструкторов значений класса case, приветствуется!