2016-10-13 7 views
0

스칼라 응용 프로그램에서 리팩토링을하는 동안 List에서 Set으로 변경하면 이전에는 없었던 문제가 발생했습니다. 나는 분산에 대해 약간의 생각을 가지고 있지만 컴파일러가 정확히 무엇을 의미하는지 이해하고 싶습니다. MyClassSet 유형의 객체를 생성,스칼라 세트, 불변 유형에 어떤 현상이 있습니까?

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

을이 시점에서 :

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

그럼 내가 설정 내 목록을 변경 :

나는 컴파일하고 잘 작동이 비슷한을했다 Set of any를 받아들이더라도 Set을 인수로 전달하는 것은 더 이상 이상하지 않습니다.

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

나는 간단한 설명은 컴파일러가 같은 요소인지 발을 추론 있다는 것을 생각 : 지금, 그것은 다음과 같은 가공 한은 (설정은 이전의 요소인지로 "동일한"이다) 때 약간 혼란 있어요 [(String, Boolean)]을 설정합니다. 그러나 SetWorks1의 인수 목록에서 직접 인스턴스화하면 Set [Any]를 받아들이므로 컴파일러에서 Set [Any]로 유추합니다. 이렇게하면 첫 번째 예제는 실패하고 두 번째 예제는 실패합니다.

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] 
  • 이 차이가 유형 차이로 인해 "임의보다 제한된 유형"의 목록을 인수로 전달할 수 있지만 경우에는 그렇지 않습니다 설정 하시겠습니까?
  • 이 차이가 유형 간 변환 또는 변환을 방해합니까?
  • 대부분이 컴파일러의 "제한 사항"입니까, 아니면 불변 유형의 예상 속성입니까?
  • "실제로"불변 유형간에 다른 차이점이 있습니까?

답변

0

1) 여기에 설명 된 것 : Why is Scala's immutable Set not covariant in its type?

기본적 세트 [T]는 또한 Function1[T, Boolean]이다. Function1의 서명은 [-In, +Out]이므로 T은 스칼라가 2 진수를 허용하지 않을 때 과 -T이 될 수 없습니다 (유형 시스템이 현저하게 약해집니다).

2) .toSet[Any] (asInstanceOf의 래퍼)을 사용하여 쉽게 캐스팅 할 수 있습니다. skip variance check으로가는 길도 있습니다.

3, 4) 일반 (다형성) 유형의 예상되는 속성입니다. 이들은 불변/공변/반 행위 일뿐만 아니라 간단한 규칙에 의해 정식으로 기술됩니다. 여기에서 설명을 읽을 수 있습니다 : https://stackoverflow.com/a/27627891/1809978

+0

링크 된 답변의 다른 모든 답글을 읽은 후 내 대답을 받아 들였습니다.1)의 실제 차이점은 Set이 불변 인 이유를 설명합니다 (또한 불변의 키를 가진 Maps를 사용하여 구현 되었기 때문에). – negative