2

scala アプリケーションでリファクタリングを行っているときに、List から Set に変更すると、以前にはなかった問題が発生する状況に遭遇しました。分散についてはある程度の考えがありますが、コンパイラにとって正確に何を意味するのかを理解したいと思います。

私はこれに似たものを持っていました.これはコンパイルしてうまく動作します:

case class MyClassList(s: List[Any])
val myList = List(("this", false)) // List[(String, Boolean)]
val listWorks = MyClassList(myList)

次に、リストを次のように変更しました。

case class MyClassSet(s: Set[Any])
val mySet = Set(("this", false)) // Set[(String, Boolean)]
val setFails = MyClassSet(mySet)

この時点で、MyClassSet 型のオブジェクトを作成することは、Set を引数として渡すことで、それが Any の Set を受け入れる場合でも、もはや問題ありません。ここで、以下が機能すると少し混乱しました (セットは以前の mySet と「同じ」であることに注意してください)。

val setWorks1 = MyClassSet(Set(("this", false)))

簡単な説明は、コンパイラが mySet val を Set[(String, Boolean)] として推論しているということだと思いますが、setWorks1 の引数リストで直接インスタンス化すると、Set[Any] を受け入れるため、コンパイラはSet[Any] として推論します。これにより、最初の例は失敗し、2 番目の例は成功します。これらのものも機能します。これは、前のものが正しいことを示しています。

val setWorks2 = MyClassSet(mySet.toSet[Any])
val mySetOfAny: Set[Any] = Set(("this", false), ("that", true), ("other", false))
val setWorks3 = MyClassSet(mySetOfAny)

コンパイラによって表示される実際のエラーは次のとおりです。

Error:(15, 55) type mismatch;
found   : Set[(String, Boolean)]
required: Set[Any]
Note: (String, Boolean) <: Any, but trait Set is invariant in type A.
You may wish to investigate a wildcard type such as `_ <: (...)

リストとセットは次のように定義されます。

type List[+A]  = scala.collection.immutable.List[A]
type Set[A]    = immutable.Set[A]
  • この違いは、「Any よりも制限された型」の List を引数として渡すことを可能にするが、Set の場合は a ではないという型の分散の違いですか?
  • この違いは、型間のキャストまたは変換を妨げているだけですか?
  • これは主にコンパイラの「制限」ですか、それとも不変型の予想されるプロパティですか?
  • 「実際には」不変型の間に他の違いはありますか、それともこのようなキャストに要約されますか?
4

1 に答える 1

5

1) ここで説明されています: なぜ Scala の不変の Set はその型で共変でないのですか?

基本的に Set[T] もFunction1[T, Boolean]. のシグネチャはFunction1is[-In, +Out]であるため、同時にT両方にすることはできません+T-T同時に、scala では双分散が許可されていません (型システムが大幅に弱体化します)。

.toSet[Any]2) (これは のラッパーです)を使用して簡単にキャストできますasInstanceOfバリアンス チェックをスキップする方法もあります。

3, 4) ジェネリック (ポリモーフィック) 型の期待されるプロパティです。それらは不変/共変/反変(だけでなく)である可能性があり、単純なルールによって正式に記述されます。ここで説明を読むことができます: https://stackoverflow.com/a/27627891/1809978

于 2016-10-13T10:29:23.183 に答える