Scala没有enum像Java那样的类型安全.给定一组相关常量,Scala表示这些常量的最佳方法是什么?
在Java中你可以:
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();
}
Run Code Online (Sandbox Code Playgroud)
你是如何在Scala中做到这一点的?
编辑/有用的链接:
我只是想知道是否有可能在Scala中迭代密封的特征?如果没有,为什么不可能?由于特性是密封的,应该可以吗?
我想做的是这样的:
sealed trait ResizedImageKey {
/**
* Get the dimensions to use on the resized image associated with this key
*/
def getDimension(originalDimension: Dimension): Dimension
}
case class Dimension(width: Int, height: Int)
case object Large extends ResizedImageKey {
def getDimension(originalDimension: Dimension) = Dimension(1000,1000)
}
case object Medium extends ResizedImageKey{
def getDimension(originalDimension: Dimension) = Dimension(500,500)
}
case object Small extends ResizedImageKey{
def getDimension(originalDimension: Dimension) = Dimension(100,100)
}
Run Code Online (Sandbox Code Playgroud)
通过给枚举值赋予实现,我可以用Java完成.Scala中有同等的东西吗?
我的工作场所一直在尝试从Java迁移到Scala执行某些任务,并且它适用于我们正在做的事情.但是,一些预先存在的测井方法需要一个java.lang.Enum.日志记录方法在(Java)基类中定义,子类可以定义自己的枚举,记录器将跟踪多个线程/机器中的所有实例.
它在Java中的工作原理如下:
public class JavaSubClass extends JavaBaseClass {
enum Counters {
BAD_THING,
GOOD_THING
}
public void someDistributedTask() {
// some work here
if(terribleThing) {
loggingMethod(Counters.BAD_THING)
} else {
loggingMethod(Counters.GOOD_THING)
// more work here
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,当任务完成后,我们可以看到
BAD_THING: 230
GOOD_THING: 10345
Run Code Online (Sandbox Code Playgroud)
有没有办法在Scala中复制它,通过创建Java Enum或转换Enumeration为Enum?我试过Enum直接扩展,但它似乎是密封的,因为我在控制台中得到错误:
error: constructor Enum in class Enum cannot be accessed in object $iw
Access to protected constructor Enum not permitted because
enclosing object $iw is not a subclass of …Run Code Online (Sandbox Code Playgroud) 在Java中,我有类似的东西
public enum FlatFileHeaderMapping {
HEADER_EL(1),
HEADER_RESERVED1(5),
HEADER_RESERVED2(2),
HEADER_MESSAGE_TYPE(4)
public final int fieldSize;
private FlatFileHeaderMapping(int fieldSize) {
this.fieldSize = fieldSize;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我可以使用它将每一行放入地图,然后通过此枚举访问地图中的键(如符号)
就我所见,枚举没有这种质量,并且case类没有像枚举声明那样排序 - 因此不能用于匹配记录布局,如上所示.至少在没有有序集合的支持下.
我可能会遗漏一些明显的东西,因此这个问题!
谢谢
射线
可能重复:
为什么单例对象更面向对象?
为什么Scala对Singleton反模式有语言支持?如果Scala static从Java 继承了该关键字,那么该关键字的合法用例object是什么?
我创建了一个名为LogActor的akka actor.LogActors的receive方法处理来自其他actor的消息并将它们记录到指定的日志级别.
我可以通过两种方式区分不同的关卡.第一个:
import LogLevel._
object LogLevel extends Enumeration {
type LogLevel = Value
val Error, Warning, Info, Debug = Value
}
case class LogMessage(level : LogLevel, msg : String)
Run Code Online (Sandbox Code Playgroud)
第二个:( 编辑)
abstract class LogMessage(msg : String)
case class LogMessageError(msg : String) extends LogMessage(msg)
case class LogMessageWarning(msg : String) extends LogMessage(msg)
case class LogMessageInfo(msg : String) extends LogMessage(msg)
case class LogMessageDebug(msg : String) extends LogMessage(msg)
Run Code Online (Sandbox Code Playgroud)
哪种方式更有效?是否需要更少的时间来匹配案例类或匹配枚举值?
(我读过这个问题,但没有任何答案提到运行时问题)
我正在尝试为Scala 实现Plurk API,但我有一个设计选择.
例如,Plurk用户的性别属性可以是"男性","女性","其他"之一.
sealed trait Gender
object Male extends Gender
object Female extends Gender
object Others extends Gender
Run Code Online (Sandbox Code Playgroud)
问题是我应该像上面的代码示例那样更喜欢密封的类/对象,而不是Enumeration来表示枚举类型?
因为我发现当我使用其他Scala库时很少遇到Enumeration,并且很多Actor的教程使用密封的类/对象来表示Actor的消息.
那么这是否意味着在Scala中,密封类是比Enumeration更好/更传统的选择?
对于我的一个项目,我已经实现了一个基于的枚举
trait Enum[A] {
trait Value { self: A =>
_values :+= this
}
private var _values = List.empty[A]
def values = _values
}
sealed trait Currency extends Currency.Value
object Currency extends Enum[Currency] {
case object EUR extends Currency
case object GBP extends Currency
}
Run Code Online (Sandbox Code Playgroud)
来自Case对象与Scala中的枚举.我工作得很好,直到遇到以下问题.Case对象似乎很懒惰,如果我使用Currency.value,我可能实际上得到一个空列表.可以在启动时对所有枚举值进行调用,以便填充值列表,但这将有点击败这一点.
因此,我冒险进入scala反射的黑暗和未知的地方,并根据以下SO答案提出了这个解决方案.我是否可以获得所有案例对象的编译时列表,这些案例对象派生自Scala中的密封父代? 和我怎样才能获得通过斯卡拉2.10反射提到了实际的对象?
import scala.reflect.runtime.universe._
abstract class Enum[A: TypeTag] {
trait Value
private def sealedDescendants: Option[Set[Symbol]] = {
val symbol = typeOf[A].typeSymbol
val internal = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol]
if (internal.isSealed)
Some(internal.sealedDescendants.map(_.asInstanceOf[Symbol]) - symbol) …Run Code Online (Sandbox Code Playgroud) 我已经看过关于模拟Javaenum和案例类与Enumeration的Scala问题,但似乎太多的努力,太少的好处.
基本上我想有一个values方法返回所有单例对象DayOfWeek而不重复自己几次.
这就是我的代码应该是这样的:
object DayOfWeek extends MyEnum {
object MONDAY extends DayOfWeek(1)
object TUESDAY extends DayOfWeek(2)
object WEDNESDAY extends DayOfWeek(3)
object THURSDAY extends DayOfWeek(4)
object FRIDAY extends DayOfWeek(5)
object SATURDAY extends DayOfWeek(6)
object SUNDAY extends DayOfWeek(7)
}
class DayOfWeek(ordinal: Int)
Run Code Online (Sandbox Code Playgroud)
该方法values应返回类似如下所示的内容:
val values = Array(MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
FRIDAY, SATURDAY, SUNDAY)
Run Code Online (Sandbox Code Playgroud)
一切都应该在MyEnum特质中发生,所以我只需要扩展它来获得功能.
trait MyEnum {
val values = this.getClass.getField("MODULE$") etc. etc.
}
Run Code Online (Sandbox Code Playgroud)
有什么建议可以做到这一点吗?这个想法是values访问类并找到它们正在扩展的类的所有单例对象. …
scala ×10
enums ×8
java ×3
enumeration ×2
scala-macros ×2
actor ×1
akka ×1
case-class ×1
object ×1
reflection ×1
scala-2.10 ×1
sealed ×1
singleton ×1
static ×1