为了账号安全,请及时绑定邮箱和手机立即绑定

Scala中的CASE对象与数字

Scala中的CASE对象与数字

Scala中的CASE对象与数字是否有关于何时使用的最佳实践指南?案例类(或case对象)VS扩展Scala中的枚举?他们似乎提供了一些同样的好处。
查看完整描述

3 回答

?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

一个很大的区别是Enumeration我们支持从name绳子。例如:

object Currency extends Enumeration {
   val GBP = Value("GBP")
   val EUR = Value("EUR") //etc.}

然后你就可以:

val ccy = Currency.withName("EUR")

当希望持久化枚举(例如,到数据库)或从驻留在文件中的数据创建枚举时,这是非常有用的。但是,总的来说,我发现Scala中的枚举有点笨拙,而且感觉上有点笨拙,所以我现在倾向于使用case object斯甲case object比枚举更灵活:

sealed trait Currency { def name: String }case object EUR extends Currency { val name = "EUR" }
 //etc.case class UnknownCurrency(name: String) extends Currency

所以现在我的优势是.。

trade.ccy match {
  case EUR                   =>
  case UnknownCurrency(code) =>}

@chaotic3quilibrium指出(并作了一些更正以方便阅读):

关于“未知数(代码)”模式,除了“破坏”封闭集属性之外,还有其他方法可以处理不查找货币代码字符串的问题。Currency类型。UnknownCurrency类型存在Currency现在可以潜入API的其他部分。

把那个箱子推到外面是明智的Enumeration并让客户处理Option[Currency]类型将清楚地表明确实存在匹配问题,并“鼓励”API的用户自己解决这个问题。

为了跟进这里的其他答案,主要的缺点是case objectS结束Enumerations如下:

  1. 不能遍历“枚举”的所有实例..当然是这样,但我发现在实践中这是非常罕见的。

  2. 无法从持久化值轻松实例化..这也是正确的,但是,除了大量枚举(例如,所有货币)之外,这并不会带来很大的开销。


查看完整回答
反对 回复 2019-07-15
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

case对象已经为它们的toString方法返回了它们的名称,因此没有必要单独传递它。这里有一个类似于Jho的版本(为了简洁起见省略了方便的方法):

trait Enum[A] {
  trait Value { self: A => }
  val values: List[A]}sealed trait Currency extends Currency.Valueobject Currency extends Enum[Currency] {
  case object EUR extends Currency
  case object GBP extends Currency
  val values = List(EUR, GBP)}

对象很懒;通过使用VALL,我们可以删除列表,但必须重复名称:

trait Enum[A <: {def name: String}] {
  trait Value { self: A =>
    _values :+= this
  }
  private var _values = List.empty[A]
  def values = _values}sealed abstract class Currency(val name: String) extends Currency.Valueobject Currency extends Enum[Currency] {
  val EUR = new Currency("EUR") {}
  val GBP = new Currency("GBP") {}}

如果您不介意一些欺骗,您可以使用反射API或类似GoogleReflets之类的工具预加载枚举值。非惰性的CASE对象为您提供了最干净的语法:

trait Enum[A] {
  trait Value { self: A =>
    _values :+= this
  }
  private var _values = List.empty[A]
  def values = _values}sealed trait Currency extends Currency.Valueobject Currency extends Enum[Currency] {
  case object EUR extends Currency
  case object GBP extends Currency}

很好,很干净,具有CASE类和Java枚举的所有优点。就个人而言,我定义了对象外部的枚举值,以便更好地匹配惯用Scala代码:

object Currency extends Enum[Currency]sealed trait Currency extends Currency.Valuecase object EUR extends Currencycase object GBP
 extends Currency


查看完整回答
反对 回复 2019-07-15
  • 3 回答
  • 0 关注
  • 797 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信