使用案例对象

时间:2016-03-03 15:30:53

标签: scala enums

我正在尝试使用案例对象模拟枚举行为。 它感觉有点冗长,而不是优雅,我想知道是否有更好的方法来实现这一目标。

所以这是一个例子:

sealed trait Operator
object Operator{
  def apply(value: String) = value match {
    case EqualsOp.name => EqualsOp
    case NotEqualOp.name => NotEqualOp
    case ContainsOp.name => ContainsOp
    case NotContainsOp.name => NotContainsOp
    case _ => UnknownOp
  }
}

case object EqualsOp extends Operator { val name = "equals" }
case object NotEqualOp extends Operator { val name = "not_equals" }
case object ContainsOp extends Operator { val name = "contains" }
case object NotContainsOp extends Operator { val name = "not_contains" }

有没有更好的方法来从字符串到实际案例对象进行反向映射? 或者一般来说更好地实现这个?

3 个答案:

答案 0 :(得分:12)

我更喜欢这种方法:

ProgressStatus.IN_PROGRESS.value

获取值:

ProgressStatus.values

获取所有值:

  public bool AddNewNews(NEWS nws)
    {
        bool status = false;

        try
        {

                DatabaseProviderFactory factory = new DatabaseProviderFactory();
                Database db = factory.Create("CharikaConString");

                con.Open();

                string query = @"INSERT INTO NEWS_TBL(NewsID,NAME) 
                                 VALUES(newsid.nextval,:NAME)";


                cmd = db.GetSqlStringCommand(query);

                db.AddInParameter(cmd, "NAME", DbType.String, nws.NAME);

                db.ExecuteNonQuery(cmd);
// In the below commented lines are,I tried to insert second table but not success.
                  // String query2 = "Select newsid.currval";

                 //string query2 = @"INSERT INTO DTL_TBL(DtlId,desc) VALUES (newsid.currval,nws.Desc)";
                // cmd = db.GetSqlStringCommand(query);

                 //db.AddInParameter(cmd, "desc", DbType.String, nws.Desc);

                // db.ExecuteNonQuery(cmd);

        }
        catch (Exception ex)
        {

            throw;
        }
        finally
        {
            con.Close();
        }
        return status;
    }

答案 1 :(得分:2)

enumerations中的基本Scala笨拙:

  1. 如果你想在模式匹配中使用它们,你将看不到编译器的下一个警告"匹配可能不是详尽的" ,你可能会意外地面对{{ 1}}在运行时。
  2. 它们与Java的枚举不兼容 - 如果你不支持Java的API,它不是很可怕,但是如果你这样做,那对你来说可能是一个意想不到的失望。
  3. 由于擦除后相同类型的枚举这一事实导致Scala的枚举无效,因此重载。因此下一个代码快照无效:

    scala.MatchError
  4. 它将抛出object WeekDays extends Enumeration { val Mon, Tue, Wed, Thu, Fri = Value } object WeekEnds extends Enumeration { val Sat, Sun = Value } object DaysOperations { def f(x: WeekEnds.Value) = "That's a weekend" def f(x: WeekDays.Value) = "That's a weekday" } 。 如您所见,error: double definition: have the same type after erasure: (x: Enumeration#Value)String不是用户友好的,并且不想使用它,它会让您的生活更轻松。

    正确的方法: 正确的方法是使用scala.Enumerationcase objectobject类的组合:

    sealed

    另外,您不能将object WeekDays { sealed trait EnumVal case object Mon extends EnumVal case object Tue extends EnumVal case object Wed extends EnumVal case object Thu extends EnumVal case object Fri extends EnumVal val daysOfWeek = Seq(Mon, Tue, Wed, Thu, Fri) } 用于枚举:

    wrapper object

    利用第三方库 - Enumeratum也可以解决sealed trait Day { def description: String } case object Monday extends Day { val description = "monday is awful" } 的问题,它是一种类型安全且功能强大的枚举实现,易于使用和理解。

    scala.enumeration

答案 2 :(得分:-2)

我更喜欢这种方法

object ServiceState  extends Enum {
  sealed trait EnumVal extends Value with Serializable
  val ERROR = new EnumVal { val name = "error" }
  val OK  = new EnumVal { val name = "ok" }
}

ScalaEnum

这有什么好处,你可以使用这种模式

object EnumImplicits {
   /**
   * Produce a JSON formatter for the Enum type
   *
   * e.g. implicit val interactionLineReasonFormat = enumFormat(InteractionLineReason)
*
* @param ev The enclosing enum "object" to provide a formatter for  that extends Enum
* @tparam A Implied from "ev"
 * @return A JSON reader and writer format
*/
def enumFormat[A <: Enum](ev: A): Format[A#EnumVal] =
new Format[A#EnumVal] {
  override def reads(json: JsValue): JsResult[A#EnumVal] = {
    json match {
      case JsString(s) =>
        ev.values.find( _.name == s ).map(JsSuccess(_)).getOrElse(JsError(s"$s is not a valid InteractionType"))
      case _ =>
        JsError(s"${json.toString()} is not a valid InteractionType")
    }
  }
  override def writes(o: A#EnumVal): JsValue = JsString(o.toString())
 }
}