問題タブ [generic-variance]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scala - Scala - 引数として渡されたものと同じ型を返す
クラス A、B、C が継承するクラス M があるとします。
そして、私はこのようなことをしたいはずです:
Wheretransform
は基本的に各サブタイプに対して同じことを行い、結果オブジェクトの構築方法のみが異なります。
私には不可能な予感があり、コードをコピーして別の変換メソッドを作成するか、型キャストに頼る必要があります。それとももっと良い方法がありますか?
編集
def transform[T<:M](t:T):T
動作しないことに注意してください。A、B、または C を返そうとすると、以下のエラー メッセージが表示されます。
型 A の式が期待される型 T に準拠していません
型 B の式が期待される型 T に準拠していません
型 C の式が期待される型 T に準拠していません
編集2 おそらく、私がやろうとしていることに関するより詳細な情報:
そのようにすると、キャストが必要になります。
私が排除したいもの。
c# - ジェネリック パラメーターのジェネリック パラメーターにアクセスしていますか?
C#の問題で困っています。
私が取り組んでいるプロジェクトには、consumable
情報を格納するクラスがいくつかありconsumer
、それらの消費可能なクラスを使用するクラスがあります。
私は次のようなより簡単な方法で物事を複製しました:
これは完全に正常に動作します。ただし、コンストラクター (または別のメソッド) で別のオブジェクトmiddle
を受け取り、Feed 呼び出しをオブジェクトにリダイレクトするコンシューマーもいくつか必要です。consumer
例えば:
そして、私はそれを次のように使用します:
ただし、 や などの他の具象クラスと一緒に使用しMiddleConsumer
ます。したがって、パラメーターを明示的に指定する必要はありません。実際の s 型から取得できます。明確にさせてください。私はこのようなものが欲しいです:(これは有効なC#コードではないことに注意してください)Consumer
BaseConsumer
DerivedConsumer
T
Consumer
ただし、予想どおり、奇妙なジェネリックパラメーターがあるため、これは機能しません。
基本型がわからない Consumer を使用して MiddleConsumer オブジェクトを作成できるようにしたいと考えています。つまり、これができるようになりたいです:
withを使用するときにコンパイラがそれを参照するだけでよいため、withBaseConsumer
を使用するたびに -example- の基本型をチェックしたくありません。何十もの異なるクラスが存在する可能性があることに注意してください。MiddleConsumer
Consumer
MiddleConsumer
Consumer
私の質問は次のとおりです: C# コンパイラにジェネリック パラメーターから消費可能な型を推測させる方法はありますか?MiddleConsumer
ご協力ありがとうございました!
scala - Scala の共分散と下限がわからない
私は現在scalaを学んでおり、分散注釈、特に共分散と反分散について混乱しています。
だから私はいくつかの研究を行い、次の例に出くわしました
これは、クラス Box が T で共変であることを意味します。これは、Cat が Animal のサブクラスであるため、Box[Cat] が Box[Animal] のサブクラスであることを意味します。私はこれを理解しています。しかし、メソッドのパラメーターに関しては、私の理解は終わりです。仕様によると、メソッドのパラメーターは共変にできないため、この下限の注釈を使用する必要があります。
メソッド定義を見てみましょう
したがって [U >: T] は、U が T のスーパークラスでなければならないことを示しています。
次のコードを試す
期待どおりに動作しますが、これは私を夢中にさせます
INTはAnimalのスーパークラスであるAnyに解決されるため、 INTを Box of Animalsに入れることは論理的に意味がありません。
だから私の質問は
put method
動物のサブタイプのみを受け入れるコードをどのように適応させる必要がありますか? 上限アノテーションが使えない
このよく知られたエラーが発生するので
共変の型 T は、型の反変の位置で発生します
scala - Scala 関数の分散 (共分散と反分散)
Scala を使用して FP の概念に飛び込んでいます。共変性と反変性とは何か、関数型が引数の型で反変であり、戻り値の型で共変である理由をようやく理解できたと思います。しかし、まだわからないことがあります。Scala では、 aにはwhereを取るList[+A]
prepend( +:
) メソッドがあります。型が an の場合、コンパイラはエラーをスローします: covariant parameter in contravariant position,関数定義でaを宣言すると共変になる理由がわかりません。私が理解している限り、共分散と反分散は、モナドや関数よりも複雑な型に関連しています。S
S >: A
A
List[+A]
A
A
Scala リスト: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List
c# - Func との共変/反変パラメータとして
次のようなインターフェースがあるとします
TIn
反変であり、TOut
共変です。
ここで、呼び出し元が入力の値に対して実行される関数を指定できるようにしたいので、単純に次のメソッドをインターフェイスに追加します。
これは…機能しません。TIn
共変であり、反変である必要がありますTOut
。
メソッドの入力として共変のジェネリック型を使用できないことは理解していますが、それ自体がバリアンス ( Func<in T1, out TResult>
) を指定するネストされたジェネリック型で使用できると考えました。
co-/contravariant 型で新しいデリゲート型を作成しようとしましたが、この型の引数を受け入れるようにインターフェイスを変更しましたが、役に立ちませんでした (同じエラー)。
コンパイラを満足させる方法はありますか? これは可能ですか (たとえば、他のネストされた型、または追加のジェネリック引数を使用)? そうでない場合、なぜですか?
c# - クラス型パラメータの分散が、そのメソッドの戻り値/引数型パラメータの分散と一致しなければならないのはなぜですか?
苦情は次のとおりです。
しかし、これがタイプセーフではない場所を想像することはできません。(中略*) これが許可されていない理由ですか、それとも私が認識していない型の安全性に違反する他のケースがあるのでしょうか?
* 私の最初の考えは確かに複雑でしたが、それにもかかわらず、回答は非常に徹底しており、@Theodoros Chatzigiannakisは私の最初の仮定を驚くほど正確に分析しました。
振り返ってみると、 の型シグネチャが に代入されたときにの型シグネチャが のICovariant::M
ままであると誤って想定していたことに気付きました。次に、それを に割り当てると、から来ると問題ないように見えますが、もちろん違法です。この最後の、明らかに違法なキャストを禁止しないのはなぜですか? (ので、私は考えました)Func<IInvariant<Derived>>
ICovariant<Derived>
ICovariant<Base>
M
Func<IInvariant<Base>>
ICovariant<Base>
エリック・リッパートも指摘しているように、この誤った接線の推測は質問から逸れていると思いますが、歴史的な目的のために、切り取られた部分は次のとおりです。
私にとって最も直感的な説明は
ICovariant
、例として、共変は、メソッドがどこかにキャストされる可能性があるTCov
ことを意味し、inの不変性に違反するということです。ただし、この含意は必要ではないようです。onの不変性は、 のキャストを許可しないことで簡単に強制できます。IInvariant<TCov> M()
IInvariant<TSuper> M()
TSuper super TCov
TInv
IInvariant
IInvariant
TInv
M
function - Kotlin: ラムダとジェネリックとの混同
コメントのエラー メッセージを参照してください。
キーポイント:
bookPrint()
authorPrint()
どちらもnullの本/著者を取る必要がありますprintIt()
これらの関数のいずれかを取る必要があります。
したがって、「プロデューサー拡張、コンシューマースーパー」と考えると、私の問題は、入力パラメーターが反変(「in」)になるようにハードコーディングされている場合に、入力パラメーターを共変にしたいことだと思います。
私はうまくいかなかったこの考えを持っていました: