0

コードの繰り返しパターンに気づき、構造型を試してみるのは良い考えかもしれないと思いました。私はその章を読みました;-)、しかし私はそれについて頭を完全に理解することができません。次のコードを検討してください。

  def link(user: User, group: Group) = {
    UserGroupLinks.insert((user.id, group.id))
  }

  def link(group: Group, role: Role) = {
    GroupRoleLinks.insert((group.id, role.id))
  }

  def link(user: User, role: Role) = {
    UserRoleLinks.insert((user.id, role.id))
  }

それを次のようなものに組み合わせるにはどうすればよいですか?

def link(A <: ...something with an id, B<:... something with and id) = {
  (A, B) match {
    case (u: User,  g: Group) =>  UserGroupLinks.insert((user.id, group.id))
    case (g: Group, r: Role)  =>  GroupRoleLinks.insert((group.id, role.id))
    case (u: User,  r: Role)  =>  UserRoleLinks.insert((user.id, role.id))
    case _ =>
  }
}
4

3 に答える 3

2

構造タイプの場合、次のようになります。

type WithId = {def id:Int}

def link(a:WithId, b:WithId) =
  (a, b) match {
    case (u:User, g:Group) => UserGroupLinks.insert(u.id -> g.id)
    case _ =>
  }

編集

もう少し進んで、コンパイラが正しいインサータを選択するのを手伝ってもらうことができます。そのためには、インサーターに特性を導入する必要があります。

trait WithInsert[A, B] {
  def insert(x: (Int, Int)): Unit
}

次に、挿入オブジェクトでこれを行います。

object UserGroupLinks extends WithInsert[User, Group]

コンパニオンオブジェクトでデフォルトのものを定義できます

object WithInsert {
  implicit val ug = UserGroupLinks
  implicit val gr = GroupRoleLinks
}

WithIdほとんどの場合、トレイトを使用することをお勧めしますが、このタイプは引き続き使用できます

type WithId = { def id: Int }

リンクメソッドは次のようになります。

def link[A <: WithId, B <: WithId](a: A, b: B)(implicit inserter: WithInsert[A, B]) =
  inserter.insert(a.id -> b.id)

ご覧のとおり、リンクメソッドはが利用可能であることを期待しWithInsert[A, B]ています。のコンパニオンオブジェクトで適切なものが見つかりますWithInsert

つまり、次のようにメソッドを呼び出すことができます。

link(user, group)
link(group, role)
于 2013-02-25T18:58:55.423 に答える
0

これは私が探していた簡単な解決策です:

  def link[A <: { def id: Long }, B <: { def id: Long }](a: A, b: B) = {
    (a, b) match {
      case (u: User, g: Group) => UserGroupLinks.insert((u.id, g.id))
      case (g: Group, r: Role) => GroupRoleLinks.insert((g.id, r.id))
      case (u: User, r: Role)  => UserRoleLinks.insert((u.id, r.id))
      case _ => ???
    }
  }

コンパイラが許可する場所:

case class XX(id:  Long)
case class YY(id:  Long)
case class ZZ(idz: Long)

link(XX(22), YY(33))

だがしかし:

link(XX(22), ZZ(33))
于 2013-02-26T01:14:43.737 に答える
0

試す

type T = { val id: String }

def link(obj1 : T, obj2: T) = {
   // You got 
   println(" obj1.id = %s obj2.id = %s".format(obj1.id, obj2.id))  
} 
于 2013-02-26T09:06:10.533 に答える