2

2 つのクラス タイプを比較できる関数を定義したいと考えています。2 つの異なるクラスを定義しました。

abstract class Task
case class DefinedTask(id: Long) extends Task
case class EmptyTask() extends Task  

次に、タイプ のオブジェクトを返す関数があります。これは または のTaskいずれDefinedTaskEmptyTaskです。

ここで、私がやりたいのは、このオブジェクトが であるDefinedTaskか、単なる であるかを識別する関数を用意することEmptyTaskです。問題は単純です。パターン マッチングを使用します。Defined/Emptyしかし、複数のクラスがこのパターン に当てはまるため、一般化したいと思います。

私がこれまでに試したことは次のとおりです。

def makeReturned[T: Manifest, U: Manifest](obj: T)(u: U)(f: T => Value) = 
   if(manifest[U] equals manifest[T]) f(obj) else
     throw new IllegalArgumentException()
}
//call to it
makeReturned(task)(DefinedTask)(makeTask)

Uは常にDefinedTaskであり、TどちらでもかまいませんがDefinedTask or EmptyTask、 として返されTaskます。

manifest[U].erasure.toString //"class DefinedTask$"
manifest[T].erasure.toString //"class Task"  

これはコンパイラの観点からは正しいですが、私には向いていません。それで、私の質問は、私が望むものを得る方法でそれらを比較するにはどうすればよいですか?

4

2 に答える 2

1

コンパイル時のチェックではなく、実行時のチェックが必要なようです。だから私はあなたが意味すると思います

def makeReturned[U <: Task, T <: Task](obj: T)(u: U)(f: T => Value) = {
  if (obj.getClass.isInstance(u.getClass)) f(obj)
  else throw new IllegalArgumentException
}

またはそのようなもの。上のメソッドを見て、java.lang.Classあなたが望むことをするものを選んでください。

于 2012-11-07T18:29:07.893 に答える
1
  1. あなたのコードにはいくつかの間違いがあります:
    • abstract class Task網羅的なパターン マッチングを行うには、sealed を作成する必要があります。
    • 空のケース クラスは非推奨です。コンパイラはそれについて警告しているはずです。case object EmptyTask extends Taskが正しい代替手段になります
  2. ケース クラスとケース オブジェクトの両方が trait を拡張しますProduct。次のいずれかの方法で、製品が空であることを確認できます。
    • task.productArity == 0
    • task.productIterator.isEmpty
  3. あなたの問題に再びアプローチする方がはるかに良いと思います。標準Optionを使用して、単純なインスタンスをcase class Task(id: Int)それにラップしてみませんか? これは、あなたの他のすべての同様のエンティティに対する一般的なアプローチである可能性があります。
于 2012-11-07T21:02:01.183 に答える