Scala中的CASE对象与数字

Scala中的CASE对象与数字

是否有关于何时使用的最佳实践指南?案例类(或case对象)VS扩展Scala中的枚举?

他们似乎提供了一些同样的好处。


阿晨1998
浏览 762回答 3
3回答

慕尼黑8549860

一个很大的区别是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如下:不能遍历“枚举”的所有实例..当然是这样,但我发现在实践中这是非常罕见的。无法从持久化值轻松实例化..这也是正确的,但是,除了大量枚举(例如,所有货币)之外,这并不会带来很大的开销。

qq_花开花谢_0

case对象已经为它们的toString方法返回了它们的名称,因此没有必要单独传递它。这里有一个类似于Jho的版本(为了简洁起见省略了方便的方法):trait&nbsp;Enum[A]&nbsp;{ &nbsp;&nbsp;trait&nbsp;Value&nbsp;{&nbsp;self:&nbsp;A&nbsp;=>&nbsp;} &nbsp;&nbsp;val&nbsp;values:&nbsp;List[A]}sealed&nbsp;trait&nbsp;Currency&nbsp;extends&nbsp;Currency.Valueobject&nbsp;Currency&nbsp;extends&nbsp;Enum[Currency]&nbsp;{ &nbsp;&nbsp;case&nbsp;object&nbsp;EUR&nbsp;extends&nbsp;Currency &nbsp;&nbsp;case&nbsp;object&nbsp;GBP&nbsp;extends&nbsp;Currency &nbsp;&nbsp;val&nbsp;values&nbsp;=&nbsp;List(EUR,&nbsp;GBP)}对象很懒;通过使用VALL,我们可以删除列表,但必须重复名称:trait&nbsp;Enum[A&nbsp;<:&nbsp;{def&nbsp;name:&nbsp;String}]&nbsp;{ &nbsp;&nbsp;trait&nbsp;Value&nbsp;{&nbsp;self:&nbsp;A&nbsp;=> &nbsp;&nbsp;&nbsp;&nbsp;_values&nbsp;:+=&nbsp;this &nbsp;&nbsp;} &nbsp;&nbsp;private&nbsp;var&nbsp;_values&nbsp;=&nbsp;List.empty[A] &nbsp;&nbsp;def&nbsp;values&nbsp;=&nbsp;_values}sealed&nbsp;abstract&nbsp;class&nbsp;Currency(val&nbsp;name:&nbsp;String)&nbsp;extends&nbsp;Currency.Valueobject&nbsp;Currency&nbsp;extends&nbsp;Enum[Currency]&nbsp;{ &nbsp;&nbsp;val&nbsp;EUR&nbsp;=&nbsp;new&nbsp;Currency("EUR")&nbsp;{} &nbsp;&nbsp;val&nbsp;GBP&nbsp;=&nbsp;new&nbsp;Currency("GBP")&nbsp;{}}如果您不介意一些欺骗,您可以使用反射API或类似GoogleReflets之类的工具预加载枚举值。非惰性的CASE对象为您提供了最干净的语法:trait&nbsp;Enum[A]&nbsp;{ &nbsp;&nbsp;trait&nbsp;Value&nbsp;{&nbsp;self:&nbsp;A&nbsp;=> &nbsp;&nbsp;&nbsp;&nbsp;_values&nbsp;:+=&nbsp;this &nbsp;&nbsp;} &nbsp;&nbsp;private&nbsp;var&nbsp;_values&nbsp;=&nbsp;List.empty[A] &nbsp;&nbsp;def&nbsp;values&nbsp;=&nbsp;_values}sealed&nbsp;trait&nbsp;Currency&nbsp;extends&nbsp;Currency.Valueobject&nbsp;Currency&nbsp;extends&nbsp;Enum[Currency]&nbsp;{ &nbsp;&nbsp;case&nbsp;object&nbsp;EUR&nbsp;extends&nbsp;Currency &nbsp;&nbsp;case&nbsp;object&nbsp;GBP&nbsp;extends&nbsp;Currency}很好,很干净,具有CASE类和Java枚举的所有优点。就个人而言,我定义了对象外部的枚举值,以便更好地匹配惯用Scala代码:object&nbsp;Currency&nbsp;extends&nbsp;Enum[Currency]sealed&nbsp;trait&nbsp;Currency&nbsp;extends&nbsp;Currency.Valuecase&nbsp;object&nbsp;EUR&nbsp;extends&nbsp;Currencycase&nbsp;object&nbsp;GBP &nbsp;extends&nbsp;Currency
打开App,查看更多内容
随时随地看视频慕课网APP