scala - 禁止生成申请案例类

标签 scala shapeless case-class type-safety

我正在编写一个类型安全的代码并想替换 apply()case class 生成es 与我自己的实现。这里是:

import shapeless._

sealed trait Data
case object Remote extends Data
case object Local extends Data

case class SomeClass(){
  type T <: Data
}

object SomeClass {
  type Aux[TT] = SomeClass { type T = TT }
  def apply[TT <: Data](implicit ev: TT =:!= Data): SomeClass.Aux[TT] = new SomeClass() {type T = TT}
}

val t: SomeClass = SomeClass() // <------------------ still compiles, bad
val tt: SomeClass.Aux[Remote.type] = SomeClass.apply[Remote.type] //compiles, good
val ttt: SomeClass.Aux[Data] = SomeClass.apply[Data] //does not compile, good
我要禁止val t: SomeClass = SomeClass()从编译。除了不做之外,是否有可能以某种方式做 SomeClass成为 case class ?

最佳答案

如果您想提供一些智能构造函数,并且默认构造函数会破坏您的不变量,那么通常会使用一种解决方案。为了确保只有您可以创建实例,您应该:

  • 防止使用 apply
  • 防止使用 new
  • 防止使用 .copy
  • 防止在子类可以调用构造函数的地方扩展类

  • 这是通过这个有趣的模式实现的:
    sealed abstract case class MyCaseClass private (value: String)
    object MyCaseClass {
      def apply(value: String) = {
        // checking invariants and stuff
        new MyCaseClass(value) {}
      }
    }
    
    这里:
  • abstract防止生成 .copyapply
  • sealed阻止扩展这个类( final 不允许 abstract )
  • private构造函数阻止使用 new

  • 虽然它看起来并不漂亮,但它几乎是防弹的。
    正如@LuisMiguelMejíaSuárez 指出的那样,这在您的具体情况下不是必需的,但通常可用于处理 case class 的边缘情况使用智能构造函数。

    关于scala - 禁止生成申请案例类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64453378/

    相关文章:

    scala - 如何使用宏注释将无参数构造函数添加到 Scala 案例类?

    algorithm - 将字节转换为包含 Scala 中每个单独位的 bool 数组的最快方法是什么?

    java - 如何在mongodb中获取嵌套文档

    scala - 是否可以使用适用于 Everywhere 的非对象 shapeless.Poly1?

    scala - 在 Scala 中为父类(super class)生成构造函数

    list - scala - 案例类集合列表上的自定义(复杂?)不同函数

    java - 为什么 Scala 不能声明但 undefined variable ,而 Java 可以?

    scala - 与 Scala 中的存在类型混淆

    scala - 通过隐式测试两个 scala 无形状 HList 类型的等效性

    scala - 挑选列表列表的第 N 个元素并将该值作为值列表返回