Я изучаю Scala, исходящую из фона Java, и первое, что я нашел, которое работает значительно по-другому, чем Java, это Enums. Мне удалось выполнить все, что я хотел, просто с помощью проб и ошибок, но я хотел бы лучше понять, что я делаю по пути.Enum.Value vs Enum # Значение
Из документации Scala, я сказал, чтобы создать перечисление путем расширения класса Enumeration
, и добавить значения, приравнивая их к постоянному Value
, например:
object Label extends Enumeration{
val NONE = Value
}
Это работает примерно как и ожидалось. Моя проблема связана с использованием не только перечислений, но и расширений пользовательских расширений enum. Я написал фрагмент кода как часть класса машинного обучения (теперь) для разделения данных по их меткам (например, для использования в TDIDT). Внизу это маленький кусочек, чтобы попасть туда, где я смущен. Объект Data
работает, просто чтобы попробовать.
Во-первых, заявление для печати, я думал, что это было бы верно, но это не
println(Label.NONE.equals(MessageLabel.NONE))//Thought this would be true, is false
Почему это так? Разве что хотя NONE
, что MessageLabel унаследовал, непосредственно из Label, система типов настаивает на том, что они являются разными значениями перечисления?
Во-вторых, и что более важно, я шел туда и обратно между Label.Value
и Label#Value
в основном волей-неволей. Версия, которую я отправил с:
def splitByLabel[T <: Label#Value]
trait Labelable[T <: Label#Value]
abstract class Data[T <: Label#Value]
class Message(... val label : MessageLabel.Value)
компилируется и работает правильно. Когда я изменить все #
с до .
, я получаю ошибку компиляции времени на линии splitByLabel(messages).foreach(a => println(a))
, заявив:
аргументов Прогнозных типа [MessageLabel.Value] не соответствует границам параметров типа метода splitByLabel в [T <: Label.Value]
Но когда я изменить все .
с до #
с, я получаю ошибку компиляции времени на линии class Message(val index : Int, val s : Map[Double, Int], override val label : MessageLabel#Value) extends Data[MessageLabel#Value](label)
, заявив:
Не найдено: Тип MessageLabel
Так ясно, что существует разница между ними, и каждый из них заполняет определенную роль. Может кто-нибудь помочь мне понять, в чем разница? Спасибо!
/** Enum type all labels should extend. Guarantees access of universal NONE label */
class Label extends Enumeration{
val NONE = Value
}
/** Singleton instance for accessing NONE */
object Label extends Label{}
/** Companion object to all data classes. Hosts helper methods and a runnable main method */
object Data{
/** Returns a map of lists, each list is similarly labeled data. Map is label -> list of data */
def splitByLabel[T <: Label#Value](elms : List[Labelable[T]]) : Map[T, List[Labelable[T]]] = {
def f(acc : Map[T, List[Labelable[T]]], e : Labelable[T]) : Map[T, List[Labelable[T]]] = {
if(acc.contains(e.label)){
val l = acc(e.label)
acc - e.label + ((e.label, (e :: l)))
} else{
acc + ((e.label, List(e)))
}
}
elms.foldLeft(Map[T, List[Labelable[T]]]())(f)
}
def main(args : Array[String]){
println(Label.NONE.equals(MessageLabel.NONE))
val messages : List[Message] = (0 to 10).toList.map(a =>
new Message(a, Map(), if(a % 3 == 0) MessageLabel.HAM else MessageLabel.SPAM))
splitByLabel(messages).foreach(a => println(a))
}
}
/** Implementing classes can be labeled */
trait Labelable[T <: Label#Value]{
/** Returns the label of this thing */
val label : T
/** The possible labelings for this thing */
val labels : List[T]
}
abstract class Data[T <: Label#Value](override val label : T) extends Labelable[T]{
override def toString(): String = {
if (label != null)
label.toString
else
"NO_LABEL"
}
}
object MessageLabel extends Label{
val HAM, SPAM = Value
}
/** An instance represents a sentence. */
class Message(val index : Int, val s : Map[Int, Double], override val label : MessageLabel.Value)
extends Data[MessageLabel.Value](label){
/** Returns the possible labelings for a message */
override val labels = MessageLabel.values.toList
/** Adds index to tostring at front */
override def toString() : String = {
index + "-" + super.toString
}
}