8

让我解释 ;-)

下面的两个类都在包 com.company.foo 中

RoleGroup.scala
abstract class RoleGroup
case object ADMIN extends RoleGroup
case object MEMBER extends RoleGroup

MailSender.scala
abstract class MailSender
case object ADMIN extends MailSender
case object STAFF extends MailSender
case object ACCOUNTANT extends MailSender

这里的问题是 ADMIN 是模棱两可的,因为 case 对象没有命名空间分隔。似乎每个包只能有一个唯一命名的案例对象。

我想我可以根据函数 a la mailADMIN、roleADMIN 等命名案例对象。还是我应该只创建适当的枚举而忘记案例对象?还是采取其他方法?

4

2 回答 2

13

您可以执行以下操作:

object RoleGroup {
  sealed trait RoleGroup
  case object ADMIN extends RoleGroup
  case object MEMBER extends Rolegroup
}

同样对于MailSender. 然后在您只使用一个的情况下,您可以做import MailSender._或反之亦然,但是当同时使用两个时,您将它们称为RoleGroup.ADMIN等。

您是想采用这种方法还是使用 Enums 主要取决于您打算如何使用它们。在这种方法中,每个“枚举”都是一个类型,而对于 Enums,每个枚举都是一个值。前者更适合模式匹配,因为编译器可以检查您的匹配是否详尽,后者更适合(IMO)使用序列化。

于 2012-07-12T21:15:31.787 回答
8

您在这里不需要枚举,可能在其他任何地方都不需要枚举。您所需要的只是适当的命名空间。我发现伴随对象方法是最有益的:

sealed abstract class RoleGroup
object RoleGroup {
  case object Admin extends RoleGroup
  case object Member extends RoleGroup
  // also just in case
  sealed case class SomeParameterizedGroup (
    param1: Any, 
    param2: Int
  ) extends RoleGroup
}

以这种方式使用它会让您想起 Java 的枚举,同时也为您提供 Scala 的优势:

def foo (roleGroup: RoleGroup) = 
  roleGroup match {
    case RoleGroup.Admin =>
    case RoleGroup.SomeParameterizedGroup(param1, param2) =>
  }

请注意,在 Dan 的解决方案中,类型roleGroupRoleGroup.RoleGroup,这有点不自然。另请注意,大写名称违反了 Scala 的样式约定,从上面的示例中您可以看出原因。

于 2012-07-13T09:43:45.237 回答