私は、1つのメソッドを定義するインタフェースを作成しようとしています。そのメソッドの引数の型は、インタフェースの型パラメータでなければなりません。これは、インタフェースの実装がこのパラメータに対して一意の実装を持つためです。これまでのところ良いですが、catchには、メソッドに関連付けられた型引数もパラメータに含まれています。クラス型引数として定義された型のパラメータを持つことはできますか?また、型引数はメソッドに関連付けられていますか?Kotlinでクラスと関数のジェネリックを混在させる?
別の言い方をすれば:
私は2つの実装とAPIクライアント・インターフェースを構築しようとしています。各クライアントは、彼らのrxecute
機能(RxJava +を実行して、はい、私は名前の不当誇りに思っています)に渡されRequest<T>
オブジェクトに基づいてAPI呼び出しを行います。
私の問題は、インタフェースのrxecute
メソッドを定義する方法です。私はいくつかのサンプルコードをレイアウトしてみましょう(私の実際のコードはimpl
を使用していない、心配しないでください)。
interface Request<T> // T is return type of the request
class RequestImpl<T>: Request<T> { // impl }
interface ApiClient<R : Request<*>> {
// R should somehow be of type Request<T>
fun <T> rxecute(request: R): Single<T>
}
class ApiClientImpl : ApiClient<RequestImpl<????>> {
override fun <T> rxecute(request: RequestImpl<T>): Single<T> = // impl
}
私はこのようにそれを使用できるようにしたいと思います:
val apiClient = ApiClientImpl()
apiClient.rxecute(RequestImpl<SomeClass>()).subscribe(someClassResult -> ...)
それは、このようなインターフェイスを作成するか、ジェネリック医薬品は、そのように動作しない可能ですか?
私は前に再帰的なジェネリックを見ていないが、それは絶対にbadshitです。さらに、それはコンパイルされます。私はすべてのことを実行する前にいくつかの他のコードを修正する必要がありますが、それは良いようです。 マイナー詳細;あなたは '(requestImplとしてrequestImpl)'をキャストする必要があります。これは少し醜いですが安全です。 私は私のものを修正し、それが動作していることを確認するとすぐにこれを答えてマークします。 –
@DavidWhitman、yep、 'requestImplとしてのリクエスト'は、再帰ジェネリックを使用するときに頸部で知られている痛みです。あなたは型の安全性を失うことなくビットを短くすることができます: 'RequestImplとしてのリクエスト'( ''は実行時にチェックされず、コンパイル時に一致すれば安全です) –
hotkey
恒星の答え、コードは完璧に動作しています。 Kotlinは美しい言語です。あなたの仕事のために本当にありがとう。 私は回避策がある奇妙な残りのビットが1つありましたが、他の人は意識しておきたいことがあります。私は署名 'class ApiClientWrapper、R:Request >'を持つ 'ApiClient'のラッパーを作成しました。あなたは結果を 'T'(' .map {it as T} ')にマップするために安全でないキャストを行う必要があります。これは、' fun rxecute(request:R):Single 'を使って' rxecute'呼び出しをラップします。 )なぜなら、 'request:R'は型パラメータ' Any? 'を持っているからです。 –