9

Play 2.1 では、以下のようなものを使用して、読み取りを通じて JSON から Creature オブジェクトを取得します。

implicit val creatureReads = (
  (__ \ "name").read[String] and
  (__ \ "isDead").read[Boolean] and
  (__ \ "weight").read[Float]
)(Creature.apply _)

Scala では比較的新しいので、Apply メソッドを使用せずに Creature オブジェクトを構築する他の方法があるかどうかを理解しようとしています。適用に依存する代わりに、オブジェクトを作成する匿名関数を持つことは可能でしょうか?

オブジェクトのほとんどのフィールドが欠落している可能性があるユースケースがありますが、私が持っているものからオブジェクトを構築したいと考えています。オブジェクトに対して 1 つの READ を定義し、各フィールドに対して readnullable を使用する方がよいでしょうか?

また、複雑な条件を使用することもできます。1 つのリーダーですべてのケースをキャプチャしようとするのではなく、カスタム関数を定義してビルドする方がクリーンでしょうか?

4

2 に答える 2

19

はい、もちろん、apply メソッドは、すべてのケース クラスのパラメーターを受け取るメソッドにすぎません。これは大まかに次のように変換されます。

implicit val creatureReads = (
  (__ \ "name").read[String] and
  (__ \ "isDead").read[Boolean] and
  (__ \ "weight").read[Float]
)((name: String, isDead: Boolean, weight: Float) => new Creature(name, isDead, weight))

欠落しているフィールドについては、実際にreadNullableクラスフィールドを使用してラップする必要がありますOption。オプションのフィールドに適切なデフォルトがある場合は、orElse(Reads.pure(value))代わりに使用できます。

weightはオプションでありisDead、デフォルトでは false であるとしましょう:

implicit val creatureReads = (
  (__ \ "name").read[String] and
  (__ \ "isDead").read[Boolean].orElse(Reads.pure(false)) and
  (__ \ "weight").readNullable[Float]
)(Creature.apply _)

JSON から何かを読みたくない場合もあります。その場合、1 つの可能性は値を明示的に渡すことです。

def creatureReads(createdAt: DateTime) = (
  (__ \ "name").read[String] and
  (__ \ "isDead").read[Boolean].orElse(Reads.pure(false)) and
  (__ \ "weight").readNullable[Float] and
  (__ \ "createdAt").read(createdAt)
)(Creature.apply _)
于 2013-07-23T06:34:42.037 に答える