私は Scala で typeclass パターンを使用して、有効な API シリアライズ可能なすべての型をマークしようとしています。これにより、シリアライズするものに関してコンパイル時の安全性を確保できます。基礎となるライブラリは、AnyRef
シリアル化する前に型を明示的に宣言しないと、奇妙なエラーを引き起こす可能性がある を受け入れます。
公開モデル、公開モデルのイテラブル、公開モデルのオプション、またはユニットを送信できます。
trait PublicModel
case class UserModel(name: String) extends PublicModel
sealed class SafeForPublic[-T]
implicit object PublicModelOk extends SafeForPublic[PublicModel]
implicit object IterablePublicModelOk extends SafeForPublic[Iterable[PublicModel]]
implicit object OptionPublicModelOk extends SafeForPublic[Option[PublicModel]]
implicit object UnitOk extends SafeForPublic[Unit]
このメソッドは、パラメーターの型がオプションであるメソッドを除いて、すべてに適しています。これは、None
が であるためです。これは、コンパイラに型の暗黙的なオブジェクトを検索するように指示し、Option[Nothing]
両方を見つけるだけでなく、T = Nothing
SafeForPublic[Nothing]
SafeForPublic[PublicModel]
SafeForPublic[Iterable[PublicModel]]
def boxed[T : SafeForPublic](t: Option[T]) = println("wooohoo!")
boxed(Some(None)) // works
boxed(Some(1)) // doesn't compile. Int is not a valid serializable model.
boxed(Some({})) // works
boxed(Some(UserModel("ok"))) // works
boxed(Some(Seq(UserModel("ok")))) // works
boxed(None) // doesn't compile, duplicate implicits ><
の重複する暗黙を見つけないようにコンパイラをだます方法を考えてNothing
ください。Miles Sabin が次のようなトリックを使っているのを見ました。
sealed trait NotNothing[A]{
type B
}
object NotNothing {
implicit val nothing = new NotNothing[Nothing]{ type B = Any }
implicit def notNothing[A] = new NotNothing[A]{ type B = A }
}
しかし、私はそれを使用する方法を理解できませんでした。ハーフ?