2

プロパティが次のクラスがありますOption[T]

class User extends IdBaseEntity[UUID] {
  var id: オプション[UUID] = なし
  変数名: Option[文字列] = なし
  var createdOn: Option[Date] = なし
}

一部のデータ アクセス レイヤーでは、オブジェクトが cassandra に永続化される前にこれらのプロパティが設定されていない場合、これらのプロパティを割り当てる必要があります。ここでは、createdOnプロパティのいくつかの方法を示します。これらのいずれかが最善のアプローチですか、それとも私がすべきことはありますか?

例 1

entity.createdOn = Some(entity.createdOn.map(identity).getOrElse(new Date()))

例 2

entity.createdOn = entity.createdOn.orElse(Some(new Date()))

例 3

entity.createdOn = entity.createdOn 一致 {
  case None => Some(new Date())
  ケース _ => entity.createdOn
}

例 4

entity.createdOn = entity.createdOn 一致 {
  case None => Some(new Date())
  ケース Some(x) => Some(x)
}

例 5

entity.createdOn マッチ {
  case None => entity.createdOn = Some(new Date())
  ケース _ =>;
}
4

3 に答える 3

4

マッチングOptionは実際には慣用的ではありません(IMHO)。orElseまたはを取得することを好みgetOrElseます。個人的には、例 2 を使用します。

これがあなたのユースケースに合うかどうかはわかりませんがUser、不変のケースクラスを作成する方がより慣用的です:

case class User(id: Option[UUID] = None, ...)

フィールドをcopyインプレースで更新するのではなく、次のようにします。

val updatedEntity = entity.copy(name = user.name.orElse(Some("Chris")))
于 2013-04-30T23:25:54.167 に答える
1

シナリオは「プロパティ値を取得し、いくつかの条件が満たされた場合に更新する」であるため、プロパティへのアクセスをカプセル化しようとします。例えば:

/**
 * Read+write access to property `P` of object `R`.
 */
case class Accessor[R,P](get: R => P, set: (R, P) => Unit) {
  /** Utility for updating values. */
  def update(record: R, modfn: P => P) =
    set(record, modfn(get(record)));
}

class User {
  var id: Option[Int] = None;
}
object User {
  // For each property of `User` we need to define an accessor,
  // but this is one time job:
  val idA: Accessor[User,Option[Int]] =
      Accessor((u: User) => u.id,
               (u: User, r: Option[Int]) => u.id = r);
}

object Test {
  import User._;

  // We can do a lot of stuff now with accessors, for example set
  // default values for `Option[...]` ones:
  def setDefault[A,B](record: A,
                      accessor: Accessor[A,Option[B]],
                      defPropVal: => B) =
    accessor.update(record, _.orElse(Some(defPropVal)));

  val user = new User();
  // Set user's id, if not defined:
  setDefault(user, idA, 42);
}

そのため、デフォルト値を入力するために各プロパティに特定のメソッドを定義する代わりに、各プロパティにジェネリック アクセサーを定義します。次に、それらを使用して、他のすべてのものを一般的に実装できます。

于 2013-05-01T08:48:22.783 に答える