스칼라가 자바 배경에서 나오는 것을 배우고 있으며, Java와는 상당히 다른 방식으로 작동하는 것으로 밝혀진 첫 번째 항목은 열거 형입니다. 나는 시행 착오를 통해 내가 원하는 모든 것을 성취 할 수 있었지만 나는 그 길을 따라 무엇을하고 있는지 더 잘 이해하고 싶다. 스칼라 문서에서 Enum.Value vs Enum # 값
는, 나는, 예를 클래스Enumeration
을 확장하여 열거를 생성하고, 일정한
Value
에 동일하게 설정하여 값을 추가하라고 해요 :
object Label extends Enumeration{
val NONE = Value
}
이 예상대로에 대해 작동합니다. 내 문제는 열거 형뿐만 아니라 사용자 정의 작성된 열거 형 확장의 확장을 사용하여 온다. 필자는 Machine Learning 클래스의 일부로 코드를 작성하여 레이블별로 데이터를 분리했습니다 (예 : TDIDT에서 사용하기 위해). 아래쪽에는 내가 혼란스러워하는 곳의 작은 조각이 있습니다. Data
개체는 실행 가능하며 시도해 볼 수 있습니다.
먼저, 인쇄 문에, 나는 그것이 사실 일 것이라고 생각하지만
println(Label.NONE.equals(MessageLabel.NONE))//Thought this would be true, is false
왜 이런 경우가 아닌가? MessageLabel이 상속 한 NONE
이 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 <을 준수하지 않는 : 내가
#
s의 모든.
의를 변경할 때 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
}
}