禁止生成申请案例类 [英] Prohibit generating of apply for case class
问题描述
我正在编写一个类型安全的代码,并想用我自己的实现替换为 case class
es 生成的 apply()
.这是:
I'm writing a type-safe code and want to replace apply()
generated for case class
es 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
防止生成.copy
和apply
sealed
阻止扩展此类(final
不允许abstract
)private
构造函数阻止使用new
abstract
prevents generation of.copy
andapply
sealed
prevents extending this class (final
wouldn't allowabstract
)private
constructor prevents usingnew
虽然它看起来并不漂亮,但它几乎是防弹的.
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屋!