Scala - 互斥特质

8

有没有一种方法可以定义一个共同类型的备选集合:

trait Mutability
trait Mutable extends Mutability
trait Immutable extends Mutability

并且编译器可以预先排除类似以下的问题:

object Hat extends Mutable with Immutable

我相信通过拥有一个共同的、冲突的成员,我可以强制发生一些编译错误,但错误信息有点晦涩:

trait Mutability
trait Mutable extends Mutability { protected val conflict = true }
trait Immutable extends Mutability { protected val conflict = true }

object Hat extends Mutable with Immutable

<console>:10: error: object Hat inherits conflicting members:
value conflict in class Immutable$class of type Boolean  and
value conflict in class Mutable$class of type Boolean
(Note: this can be resolved by declaring an override in object Hat.)
   object Hat extends Immutable with Mutable

有没有更直接的方式来表达这个约束,并且不允许某人通过编译器提供的提示来绕过它(在 Hat 中覆盖 'conflict')?
感谢任何见解。

这能实现什么目标?我想不起来我曾经想过要做这件事的时候。 - Daenyth
首先,感谢以下提供的想法,我还在考虑是否可以得到一个严密的解决方案(不允许过于容易出错的“MutabilityLevel[Mutability]”滑过去)。 其次,关于目标。有两个层面的目标:(1)标记特征以向处理程序发出信号,告诉它们可以安全地不处理此类型实例的更新事件,以及(2)实际上扩展Mutable特征来定义这些事件: class Events[T <: Mutable] { case class Add(T) case class Remove(T) } 例如。 - jmcnulty
class Mat(name: String) extends Mutable class Pat extends Immutable处理程序可以安全地假定 object PatEvents extends Events[Pat] 无法编译,且 PatEvents.Add/Remove 不存在。 - jmcnulty
1个回答

3

我觉得这可能可行

sealed trait Mutability
case object Immutable extends Mutability
case object Mutable extends Mutability

trait MutabilityLevel[A <: Mutability]

class Foo extends MutabilityLevel[Immutable.type]

这个(滥用?)了一个事实,即您无法使用不同的参数化两次扩展相同的特质。
scala> class Foo extends MutabilityLevel[Immutable.type] with MutabilityLevel[Mutable.type]
<console>:11: error: illegal inheritance;
 self-type Foo does not conform to MutabilityLevel[Immutable.type]'s selftype MutabilityLevel[Immutable.type]
       class Foo extends MutabilityLevel[Immutable.type] with MutabilityLevel[Mutable.type]
                         ^
<console>:11: error: illegal inheritance;
 self-type Foo does not conform to MutabilityLevel[Mutable.type]'s selftype MutabilityLevel[Mutable.type]
       class Foo extends MutabilityLevel[Immutable.type] with MutabilityLevel[Mutable.type]

然而...
scala> class Foo extends MutabilityLevel[Mutability]
defined class Foo

你可以通过将 MutabilityLevel 封装并添加另一个级别来解决这个问题,例如 trait Immutable extends MutabilityLevel[MutabilityLevel.I] - J Cracknell
@JCracknell 调用者可以扩展 Immutable 并给它不当的实现。 - Daenyth
是的,但这将阻止创建MutabilityLevel[Mutability]的过程。 - J Cracknell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接