#scala
Вопрос:
У меня есть несколько объектов перечисления следующим образом (это всего лишь примеры):
object Status extends Enumeration {
val Pending, Done = Value
}
object Gender extends Enumeration {
val Female, Male, Other = Value
}
...
И я хочу сопоставить любой расширяющийся объект Enumeration
. Этот работает:
def func(anyVal: Any): String = anyVal match {
case strVal: String => "This is a String"
case status: Status.Value => "This is an Enumeration"
case gender: Gender.Value => "This is an Enumeration"
...
}
Однако мне не нужно сопоставлять перечисления отдельно. Что-то вроде этого было бы здорово:
def func(anyVal: Any): String = anyVal match {
case strVal: String => "This is a String"
case e: Enumeration.Value => "This is an Enumeration"
}
Но это не работает. У тебя есть какие-нибудь идеи?
Ответ №1:
Попробуйте использовать проекцию типа Enumeration#Value
anyVal match {
case strVal: String => "This is a String"
case e: Enumeration#Value => "This is an Enumeration"
}
вместо Enumeration.Value
. Примечание Value
класс является членом Enumeration
класса
abstract class Enumeration {
...
abstract class Value {
...
}
}
поэтому нам нужна проекция типа, чтобы ссылаться на ее тип.
В качестве примечания, точечная нотация может использоваться только в том случае, если левая сторона является значением. Также, по возможности, старайтесь избегать Any
в дизайне, так как в некотором смысле это противоречит преимуществам использования Scala, которая содержит богатую информацию о типах.
Комментарии:
1. Спасибо вам за объяснение. Как я могу избежать использования
Any
, если у меня нет никаких ограничений для данного параметра? Эта функция является примером, но на самом деле она пытается преобразовать что-либо в значимую строку. Таким образом, функция также имеет регистр по умолчанию, напримерcase other: Any => other.toString
.2. @Alperen вам нужен класс типов : tpolecat.github.io/2013/10/12/typeclass.html