禁止生成申请案例类 [英] Prohibit generating of apply for case class

查看:47
本文介绍了禁止生成申请案例类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个类型安全的代码,并想用我自己的实现替换为 case classes 生成的 apply().这是:

I'm writing a type-safe code and want to replace apply() generated for case classes with my own implementation. Here it is:

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 之外,是否有可能以某种方式做?

I want to prohibit val t: SomeClass = SomeClass() from compiling. Is it possible to do somehow except do not SomeClass to be case class?

推荐答案

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

There is a solution that is usually used if you want to provide some smart constructor and the default one would break your invariants. To make sure that only you can create the instance you should:

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

这是通过这个有趣的模式实现的:

This is achieved by this interesing patten:

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
  • abstract prevents generation of .copy and apply
  • sealed prevents extending this class (final wouldn't allow abstract)
  • private constructor prevents using new

虽然它看起来并不漂亮,但它几乎是防弹的.

While it doesn't look pretty it's pretty much bullet proof.

正如@LuisMiguelMejíaSuárez 指出的那样,这在您的具体情况下不是必需的,但总的来说,这可用于通过智能构造函数处理 case class 的边缘情况.

As @LuisMiguelMejíaSuárez pointed out this is not necessary in your exact case, but in general that could be used to deal with edge cases of case class with a smart constructor.

这篇关于禁止生成申请案例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆