6

私は次の方法を持っています

def show[E: Writes, T: Writes](block: RequestWithUser[AnyContent] => Either[E, T]): Action[AnyContent] = {
  withErr(block)
}

コントローラーから次のように使用します。

def show(id: Long) = CrudAuthAction.show { request =>
  IdeaType.findByIdWithErr(id)
}

また、リクエスト メソッドをオプションにしたいので、同じメソッドに別の署名を定義しました。

def show[E: Writes, T: Writes](block: => Either[E, T]): Action[AnyContent] = {
  withErr(request => block)
}

そしてそれはうまくいきます、私はリクエストパラメータを省略できます

しかし、この他の方法で同じことをしようとすると

def list[T: Writes](block: RequestWithUser[AnyContent] => T): Action[AnyContent] = {
  fromRequest(block)
}

def list[T: Writes](block: => T): Action[AnyContent] = {
  fromRequest(request => block)
}

こんな感じで使いたいとき。

def list = CrudAuthAction.list { request =>
  IdeaType.find(request.queryString)
}

リクエストにパラメータータイプが欠落していることがわかるので、次のように指定する必要があります。

def list = CrudAuthAction.list { request: RequestWithUser[AnyContent] =>

最初のケースと何が違うのかわかりませんが、scala は適切なタイプのリクエストを推測できないようです...

私が目にする唯一の違いは、最初のケースではブロックが [E, T] を返しているのに対し、2 番目のケースではジェネリック T だけを返していることです...

4

1 に答える 1

5

問題は、2 番目の例では、T が関数型である可能性があるため、オーバーロードされたメソッドのどれを選択するかをコンパイラが認識できないことです。Eitherは明らかに関数ではないため、最初のケースで機能します。

この問題を回避するには、2 番目の方法を次のように変更します。

def list[T: Writes](block: => Foo[T]): Action[AnyContent] = {
  fromRequest(request => block.v)
}

Foo をそのように定義すると:

case class Foo[T](val v:T)

Writes残念ながら、型クラス内の型ごとに暗黙的な変換を作成しない限り、暗黙的な変換を Foo に追加すると、再び問題が発生します。

于 2012-10-31T08:20:44.097 に答える