[SCALA] 어떻게 스칼라에 열거하는 방법을 추가?
SCALA어떻게 스칼라에 열거하는 방법을 추가?
당신이 할 수 자바에서 :
public enum Enum {
ONE {
public String method() {
return "1";
}
},
TWO {
public String method() {
return "2";
}
},
THREE {
public String method() {
return "3";
}
};
public abstract String method();
}
당신은 어떻게 스칼라에서이 작업을 수행합니까?
EDIT / 유용한 링크 :
해결법
-
==============================
1.여기 Enumeration.Val 클래스를 확장하여 스칼라 열거 속성을 추가의 예이다.
여기 Enumeration.Val 클래스를 확장하여 스칼라 열거 속성을 추가의 예이다.
object Planet extends Enumeration { protected case class Val(val mass: Double, val radius: Double) extends super.Val { def surfaceGravity: Double = Planet.G * mass / (radius * radius) def surfaceWeight(otherMass: Double): Double = otherMass * surfaceGravity } implicit def valueToPlanetVal(x: Value) = x.asInstanceOf[Val] val G: Double = 6.67300E-11 val Mercury = Val(3.303e+23, 2.4397e6) val Venus = Val(4.869e+24, 6.0518e6) val Earth = Val(5.976e+24, 6.37814e6) val Mars = Val(6.421e+23, 3.3972e6) val Jupiter = Val(1.9e+27, 7.1492e7) val Saturn = Val(5.688e+26, 6.0268e7) val Uranus = Val(8.686e+25, 2.5559e7) val Neptune = Val(1.024e+26, 2.4746e7) } scala> Planet.values.filter(_.radius > 7.0e6) res16: Planet.ValueSet = Planet.ValueSet(Jupiter, Saturn, Uranus, Neptune)
-
==============================
2.크리스 '솔루션을 구축, 당신은 암시 적 변환 다소 더 좋은 구문을 달성 할 수있다 :
크리스 '솔루션을 구축, 당신은 암시 적 변환 다소 더 좋은 구문을 달성 할 수있다 :
object Suit extends Enumeration { val Clubs, Diamonds, Hearts, Spades = Value class SuitValue(suit: Value) { def isRed = !isBlack def isBlack = suit match { case Clubs | Spades => true case _ => false } } implicit def value2SuitValue(suit: Value) = new SuitValue(suit) }
그럼 당신은, 예를 들어, Suit.Clubs.isRed를 호출 할 수 있습니다.
-
==============================
3.스칼라 열거 자바 열거에서 구별된다.
스칼라 열거 자바 열거에서 구별된다.
지금이 순간, (제정신이 방법에서) 그것을 할 수있는 방법의 추가 방법이 없습니다. 일부 작업 어라운드하지만 모든 경우에 작동하고 구문 쓰레기처럼 보이지 않는 것도 있습니다.
나는 "((런타임에 새로운 인스턴스를 생성 할 수있는 및 객체와 클래스의 새 인스턴스 사이에 작업 등가 관계를 가지면서, 클래스의 열거 된 인스턴스에 메서드를 추가) 뭔가 비슷한 시도했지만 버그 # 4023에 의해 중단되었다 getClasses은 / getDeclaredClasses는 일부 (REPL) 또는 모든 (scalac) 클래스 (객체) 선언 ")를 그리워하는 것 같다.
내게로 이러한 관련 질문에서보세요 :
솔직히 열거를 사용하지 않을 것입니다. 이 스칼라 1.0 (2004)에서 클래스 원산지이며 (그것을 쓴 사람을 제외하고) 거기에 이상한 물건 많은없는 사람이 먼저 튜토리얼없이 사용하는 방법을 이해한다.
나는 절대적으로 열거를 필요로한다면 난 그냥 자바 클래스를 작성합니다.
-
==============================
4.당신이 열거 값을 반복하는 것을 필요로하거나 다른 열거 틱 물건을하지 않으면, 내가 대신 열거의 ADT를을 사용하여 조언을 것입니다.
당신이 열거 값을 반복하는 것을 필요로하거나 다른 열거 틱 물건을하지 않으면, 내가 대신 열거의 ADT를을 사용하여 조언을 것입니다.
sealed abstract class Enum { def method: String = this match { case One => "1" case Two => "2" case Three => "3" } } case object One extends Enum case object Two extends Enum case object Three extends Enum
이 방법을 사용하면 일치 식에 하나 또는 그 이상의 사건을 잊지 때 컴파일러가 경고 것을 열거를 통해 하나의 장점이 있습니다.
-
==============================
5.암시 적 클래스를 사용하여, 아론의 솔루션, 스칼라 2.10에서 더욱 컴팩트 한 형태의 정교화 :
암시 적 클래스를 사용하여, 아론의 솔루션, 스칼라 2.10에서 더욱 컴팩트 한 형태의 정교화 :
object Suit extends Enumeration { val Clubs, Diamonds, Hearts, Spades = Value implicit class SuitValue(suit: Value) { def isRed = !isBlack def isBlack = suit match { case Clubs | Spades => true case _ => false } } }
다음은 다음과 같이 사용할 수 있습니다 : Suit.Clubs.isRed를
-
==============================
6.이 작업을 수행 할 수 있습니다 :
이 작업을 수행 할 수 있습니다 :
object Suit extends Enumeration { val Clubs, Diamonds, Hearts, Spades = Value def isRed(suit : Value) = !isBlack(suit) def isBlack(suit : Value) = suit match { case Clubs | Spades => true case _ => false } }
분명히 이것은 완벽하지 않습니다하지만 당신은 할 수 있습니다 :
Suit.isBlack(Suit.Clubs)
-
==============================
7.스칼라의 열거 속성 및 / 또는 방법이 열거 형의 값에 추가 할 수 없습니다. 이 새로운 MyEnumeration로 다음을 수행 할 수 있습니다.
스칼라의 열거 속성 및 / 또는 방법이 열거 형의 값에 추가 할 수 없습니다. 이 새로운 MyEnumeration로 다음을 수행 할 수 있습니다.
abstract class MyEnumeration { // "Value" must be the name of the class defining your values type Value type Value // Contains your values in definition order private val vals = collection.mutable.LinkedHashMap[String, Value]() // A mixin for your values class to automatically collect the values protected trait ValuesCollector { self: Value => private val ordinal = vals.size vals += (fieldNames(ordinal) -> self) def getName = fieldNames(ordinal) override def toString = getName } def apply(ordinal: Int) = vals(fieldNames(ordinal)) def apply(fldName: String) = vals(fldName) def values = vals.values def namedValues: collection.Map[String, Value] = vals // Getting the field names through reflection. // Copied from scala.Enumeration private val fieldNames = getClass.getMethods filter (m => m.getParameterTypes.isEmpty && classOf[ValuesCollector].isAssignableFrom(m.getReturnType) && m.getDeclaringClass != classOf[MyEnumeration]) map (_.getName) }
여기 스칼라에있는 행성의 예를 참조하십시오.
object Planet extends MyEnumeration { case class Value(val mass: Double, val radius: Double) extends ValuesCollector { // universal gravitational constant (m3 kg-1 s-2) private val G = 6.67300E-11; def surfaceGravity = G * mass / (radius * radius) def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity } val MERCURY = Value(3.303e+23, 2.4397e6) val VENUS = Value(4.869e+24, 6.0518e6) val EARTH = Value(5.976e+24, 6.37814e6) val MARS = Value(6.421e+23, 3.3972e6) val JUPITER = Value(1.9e+27, 7.1492e7) val SATURN = Value(5.688e+26, 6.0268e7) val URANUS = Value(8.686e+25, 2.5559e7) val NEPTUNE = Value(1.024e+26, 2.4746e7) val PLUTO = Value(1.27e+22, 1.137e6) } object PlanetTest { def main(args: Array[String]) { val earthWeight = 175 val mass = earthWeight/Planet.EARTH.surfaceGravity for (p <- Planet.values) println("Your weight on %s is %f" format (p, p.surfaceWeight(mass))) /* Your weight on MERCURY is 66.107583 * Your weight on VENUS is 158.374842 * Your weight on EARTH is 175.000000 * Your weight on MARS is 66.279007 * Your weight on JUPITER is 442.847567 * Your weight on SATURN is 186.552719 * Your weight on URANUS is 158.397260 * Your weight on NEPTUNE is 199.207413 * Your weight on PLUTO is 11.703031 */ } }
-
==============================
8.
object Unit extends Enumeration { abstract class UnitValue(var name: String) extends Val(name) { def m: Unit } val G = new UnitValue("g") { def m { println("M from G") } } val KG = new UnitValue("kg") { def m { println("M from KG") } } }
-
==============================
9.scala.Enumeration의 소스 코드를 체크 아웃 후, 나는이있어 :
scala.Enumeration의 소스 코드를 체크 아웃 후, 나는이있어 :
object MyEnum extends Enumeration { val ONE = new Val { def method = "1" } val TWO = new Val { def method = "2" } val THREE = new Val { def method = "3" } }
그것은 익명의 클래스가 사용되기 때문에 '새'를 제거하기 어려운 것 같다. 누구나 할 방법을 알고 있으면 알려주세요 :)
-
==============================
10.당신이 절대적으로 열거 값과 값을 반복 할 수 있어야 당 방법을해야하는 경우, 당신은 이런 식으로 뭔가를 할 수 있습니다 :
당신이 절대적으로 열거 값과 값을 반복 할 수 있어야 당 방법을해야하는 경우, 당신은 이런 식으로 뭔가를 할 수 있습니다 :
object BatchCategory extends Enumeration { class BatchCategory extends Val { val isOfficial, isTest, isUser = false } val OFFICIAL = new BatchCategory { override val isOfficial = true } val TEST = new BatchCategory { override val isTest = true } val USER = new BatchCategory { override val isUser = true } // Needed to get BatchCategory from Enumeration.values implicit def valueToBatchCategory(v: Value): BatchCategory = v match { case bc: BatchCategory => bc case x => throw new IllegalArgumentException("Value is not a BatchCategory: " + x) } def valueOf(catStr: String): BatchCategory = { BatchCategory.values. find { v => val s = v.toString; s.take(1) == catStr || s == catStr }. getOrElse(throw new IllegalArgumentException("Unknown category '" + catStr + "' ! ")) } def main(args: Array[String]) { BatchCategory.values.foreach(v => println(v + " isOfficial=" + v.isOfficial)) } }
인쇄물
OFFICIAL isOfficial=true TEST isOfficial=false USER isOfficial=false
이것은 열거 외에 온건 열거 전략으로 이동할 수 없습니다 일부 레거시 코드에 대해 이루어졌다.
-
==============================
11.스칼라 열거가 인수 / 방법 - 사용자 정의 값을 지원하지 않는 것을 말한다 대답은 잘못된 것 같다. 기타 답변 (그들 중 일부는 암시 포함)가 할 수있는 것을 증명하지만 그들은 이름 중복을 요구하는 인상을 : 당신의 값이 두 번째로, 이름이 요점 반면 문자열로 값 생성자에 공급되고, 자바 객체 필드로 이름을 선언했다 열거 형의 중복없이 할 수있는 반복 가능한 이름 -> 값 맵 및 스칼라를 만드는 것입니다 :
스칼라 열거가 인수 / 방법 - 사용자 정의 값을 지원하지 않는 것을 말한다 대답은 잘못된 것 같다. 기타 답변 (그들 중 일부는 암시 포함)가 할 수있는 것을 증명하지만 그들은 이름 중복을 요구하는 인상을 : 당신의 값이 두 번째로, 이름이 요점 반면 문자열로 값 생성자에 공급되고, 자바 객체 필드로 이름을 선언했다 열거 형의 중복없이 할 수있는 반복 가능한 이름 -> 값 맵 및 스칼라를 만드는 것입니다 :
object Ops1 extends Enumeration { protected case class OpsVal(f: Int => Int) extends super.Val(/*nextId*/) val ZERO = new FuncVal (x => 0) val DOUBLE = new FuncVal (x => 2 * x ) implicit def convert(v: Value) = v.asInstanceOf[OpsVal] } // implicit is not needed Ops1.ZERO.f(1) //> res0: Int = 0 // implicit is needed Ops1.values map (v => (v + "=>" + v.f(1)))//> res1: scala.collection.immutable.SortedSet[String] = TreeSet(DOUBLE=>2, ZERO=>0)
나는 위의 더 간결가보다라고 생각합니다
object Ops2 extends Enumeration { protected abstract class OpsVal extends Val() { def f(a: Int): Int } val ZERO = new OpsVal { def f(x: Int) = 0 } val DOUBLE = new OpsVal { def f(x: Int) = 2 * x } implicit def convert(valu: Value) = valu.asInstanceOf[OpsVal] } Ops2.ZERO.f(1) // implicit is not needed //> res2: Int = 0 // implicit is needed Ops2_3.values map (v => (v, v(1))) //> res7: scala.collection.immutable.SortedSet[(e.Ops2_3.Value, Int)] = TreeSet //| ((ZERO,0), (DOUBLE,2))
값 당 하나의 방법이 있기 때문에, 우리는 함수로 변환 할 수 있습니다
object Ops2_3 extends Enumeration { protected case class FuncVal(f: Int => Int) extends Val { def apply(x: Int) = f(x) // no need to extend Function1 explicitly } val ZERO = new FuncVal (x => 0) val DOUBLE = new FuncVal (x => 2 * x ) implicit def convert(v: Value) = v.asInstanceOf[FuncVal] } Ops2_3.ZERO(1) // implicit is not needed //> res6: Int = 0 // implicit is needed Ops2_3.values map (v => (v, v(1))) //> res7: scala.collection.immutable.SortedSet[(e.Ops2_3.Value, Int)] = TreeSet //| ((ZERO,0), (DOUBLE,2))
모든 값 공유 기능은, 다음과 같이 정의 할 수 있습니다 (가능한에서 인수 파서)
val args: Array[String] = "-silent -samples 100 -silent ".split(" +").toArray //> args : Array[String] = Array(-silent, -samples, 100, -silent) object Opts extends Enumeration { val nopar, silent, samples = new Val() { def apply() = args.contains(toString) def asInt(default: Int) = { val i = args.indexOf(toString) ; if (i == -1) default else args(i+1).toInt} def asInt: Int = asInt(-1) override def toString = "-" + super.toString } } Opts.nopar() //> res0: Boolean = false Opts.samples.asInt //> res1: Int = 100
다른 사용자는 스칼라의 밀봉 특성을 통해 밀봉 특성 + 매크로, 반복의 경우에 주장?
from https://stackoverflow.com/questions/4346580/how-to-add-a-method-to-enumeration-in-scala by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라 피보나치 수의 시퀀스를 생성 [중복] (0) | 2019.11.16 |
---|---|
[SCALA] 매개 변수 유형 스칼라 asInstanceOf (0) | 2019.11.15 |
[SCALA] 스칼라 세트 같은 요소를 포함하지만, sameElements ()는 false를 돌려줍니다 (0) | 2019.11.15 |
[SCALA] 볼품를 사용하는 경우 클래스에 맵 [문자열, 어떤] 변환 (0) | 2019.11.15 |
[SCALA] 스칼라 2.8에 대한 어떤 IDE? (0) | 2019.11.15 |