복붙노트

[SCALA] 왜 예는 컴파일되지 않습니다 (공동, 콘트라 및 IN-) 분산 작업을 수행 일명 어떻게?

SCALA

왜 예는 컴파일되지 않습니다 (공동, 콘트라 및 IN-) 분산 작업을 수행 일명 어떻게?

이 질문에 이어 것은, 누군가가 스칼라에 다음과 같이 설명 할 수있다 :

class Slot[+T] (var some: T) { 
   //  DOES NOT COMPILE 
   //  "COVARIANT parameter in CONTRAVARIANT position"

}

내가 유형 선언에서 + T와 T 사이의 차이를 이해 (나는 T를 사용하는 경우는 컴파일). 하지만 어떻게 하나 실제로 일이 unparametrized 생성에 의존하지 않고 형식 매개 변수의 공변 된 클래스를 작성합니까? 어떻게 다음은 T의 인스턴스로 생성 될 수 있도록 할 수 있습니까?

class Slot[+T] (var some: Object){    
  def get() = { some.asInstanceOf[T] }
}

편집 - 이제 다음이 아래를 가지고 :

abstract class _Slot[+T, V <: T] (var some: V) {
    def getT() = { some }
}

이 모든 좋은,하지만 지금은 하나를 원하는 두 가지 유형의 매개 변수를 가지고있다. 나는 이렇게 질문을 다시 요청할 것입니다 :

어떻게 그 유형에 공변 된 불변 슬롯 클래스를 작성 할 수 있습니까?

편집 2 : 뜨아! 나는 VAR이 아닌 발을 사용했다. 다음은 내가 원하는 것입니다 :

class Slot[+T] (val some: T) { 
}

해결법

  1. ==============================

    1.일반적으로, 공변 유형 파라미터는 상기 클래스 서브 타입 화 된 바와 같이 아래로 변화시킨다이다 (다르게는, 따라서 "공동"접두사 하위 유형에 따라 다름). 보다 구체적으로 :

    일반적으로, 공변 유형 파라미터는 상기 클래스 서브 타입 화 된 바와 같이 아래로 변화시킨다이다 (다르게는, 따라서 "공동"접두사 하위 유형에 따라 다름). 보다 구체적으로 :

    trait List[+A]
    

    지능이 AnyVal의 서브 타입이기 때문에 목록 [Int 인은] 목록 [AnyVal]의 하위 유형입니다. 이것은 당신이 목록의 인스턴스를 제공 할 수 있음을 의미 [지능]이 유형의 목록 [AnyVal]의 값이 예상되는 경우. 이건 정말 제네릭이 작동 할 수있는 매우 직관적 인 방법이지만, 가변 데이터의 존재에 사용되는 때 (타입 시스템을 나누기) 불건전 한 것으로 밝혀졌습니다. 제네릭 자바 불변 이유입니다. 자바 배열을 사용 unsoundness의 간단한 예 (이 잘못 공변 있습니다) :

    Object[] arr = new Integer[1];
    arr[0] = "Hello, there!";
    

    우리는 단지 정수 [] 유형의 배열에 문자열 유형의 값을 할당. 분명해야 이유로이 나쁜 소식이다. 자바의 타입 시스템은 실제로 컴파일시에이를 수 있습니다. JVM은 "유용하게"런타임시 ArrayStoreException를 발생합니다. 어레이 클래스의 타입 파라미터는 불변이므로 스칼라 타입 시스템은 이러한 문제를 방지한다 (선언은 [A] 대신 [+ A]).

    contravariance로 알려진 분산의 또 다른 유형이 있습니다. 이 공분산 몇 가지 문제가 발생할 수 있습니다 이유를 설명 이것은 매우 중요합니다. Contravariance 그대로 공분산 반대이다 파라미터 하위 유형으로 상향 변화한다. 기능 : 그것은 하나의 매우 중요한 응용 프로그램을 않습니다 비록, 그래서 직관적이기 때문에 부분적으로 훨씬 덜 일반적입니다.

    trait Function1[-P, +R] {
      def apply(p: P): R
    }
    

    "-"P 형 매개 변수에 대한 분산 주석을 알 수 있습니다. 전체적으로이 선언은 우리가 다음과 같은 공리를 유도 할 수있다, 기능 1은 따라서 R.에서 P와 공변에 contravariant 있음을 의미합니다 :

    T1' <: T1
    T2 <: T2'
    ---------------------------------------- S-Fun
    Function1[T1, T2] <: Function1[T1', T2']
    

    그 주목 T1 '는 T2 및 T2에 대한 반대 인 반면에, T1의 서브 타입 (또는 동일한 타입)이어야'. 영어로, 이것은 다음과 같이 할 수있다 :

    이 규칙에 대한 이유는 독자에게 연습 문제로 남겨 (힌트 : 함수는 위에서 내 배열의 예와 같이, 서브 타입대로 다른 경우에 대해 생각).

    공동 및 contravariance의 새 발견 된 지식을 바탕으로, 다음의 예와 컴파일되지 않습니다 이유를 할 수 있어야한다 :

    trait List[+A] {
      def cons(hd: A): List[A]
    }
    

    문제는 반대 기능의 유형 파라미터는 불변 것으로 기대 동안은 공변 점이다. 따라서, A는 잘못된 방향으로 변화된다. 흥미롭게도, 우리는에 목록 contravariant함으로써이 문제를 해결할 수 있지만, 단점 기능은 반환 형식은 공변 될 것으로 예상로서 다음 반환 형식의 목록은 [A] 잘못된 것입니다.

    우리의 유일한 두 가지 옵션이 여기에서, 불변을 공분산의 좋은 직관적 인 서브 타이핑 속성을 잃고, 또는 b) 하한 같이 정의 단점 방법에 로컬 유형 매개 변수를 추가)를에 있습니다 :

    def cons[B >: A](v: B): List[B]
    

    이제이 유효합니다. 당신은 아래쪽으로 변화하는 것을 상상할 수 있지만, 그 하한 때문에 B는 A와 관련하여 위쪽으로 변화 할 수 있습니다. 이 방법을 선언, 우리는이 공변 될 수 있습니다 및 모든 밖으로 작동합니다.

    우리는 당신의 변수에 B 형의 값을 할당하려고 결국 때문에 일을 분해, 당신은 목록을 변경할 수 있도록하려고하면 덜 특정 유형의 B.에 전문 목록의 인스턴스를 반환하는 경우이 트릭은 작동 주목 컴파일러에 의해 허용된다를 입력. 당신은 가변성을 할 때마다, 당신은 (함께 접근로) 불변성을 의미한다 특정 유형의 메소드 매개 변수를 필요로 어떤 종류의 뮤 테이터이 필요합니다. 유일하게 가능한 동작이 공변 리턴 타입을들 수있다 접근이기 때문에 공분산 불변 데이터로 작동한다.

  2. ==============================

    2.@Daniel 아주 잘 설명하고있다. 이 허용 된 경우에, 짧은에 그것을 설명하기 :

    @Daniel 아주 잘 설명하고있다. 이 허용 된 경우에, 짧은에 그것을 설명하기 :

      class Slot[+T](var some: T) {
        def get: T = some   
      }
    
      val slot: Slot[Dog] = new Slot[Dog](new Dog)   
      val slot2: Slot[Animal] = slot  //because of co-variance 
      slot2.some = new Animal   //legal as some is a var
      slot.get ??
    

    이 개에 동물을 변환에 실패했습니다으로 slot.get는 실행시 오류가 발생합니다 (대만족을!).

    일반적으로 가변성에 공동 분산 및 콘트라 분산을 잘하지 않습니다. 즉 모든 자바 컬렉션 불변 이유입니다.

  3. ==============================

    3.이 전체 논의 예에 의해 페이지 57+를 스칼라를 참조하십시오.

    이 전체 논의 예에 의해 페이지 57+를 스칼라를 참조하십시오.

    내가 제대로 귀하의 의견을 이해 해요 경우에는 통로 기본적으로 내가 무엇을 입력-로부터 안전하지 않습니다 실행 시간 검사없이 요구하고있다 생각하는 스칼라하지 않습니다 56 페이지 (하단에서 시작하여 다시 읽도록해야합니다, 그래서 당신은) 운입니다. 자신의 예를 번역하면 구문을 사용합니다 :

    val x = new Slot[String]("test") // Make a slot
    val y: Slot[Any] = x             // Ok, 'cause String is a subtype of Any
    y.set(new Rational(1, 2))        // Works, but now x.get() will blow up 
    

    당신은 내가 당신의 질문 (별개의 가능성을) 이해하고 있지 않다 생각되면 문제 설명에 더 많은 설명 / 컨텍스트를 추가하는 시도하고 다시 시도 할 것이다.

    귀하의 편집에 대응 : 불변의 슬롯은 도움이 위 * 나는 예를 희망 완전히 다른 상황 ... * 미소입니다.

  4. ==============================

    4.당신은 매개 변수에 하한을 적용해야합니다. 나는 구문을 기억 힘든 시간을 보내고 있어요,하지만 난 그것을 다음과 같이 보일 것이라고 생각 :

    당신은 매개 변수에 하한을 적용해야합니다. 나는 구문을 기억 힘든 시간을 보내고 있어요,하지만 난 그것을 다음과 같이 보일 것이라고 생각 :

    class Slot[+T, V <: T](var some: V) {
      //blah
    }
    

    스칼라 별 예제는 조금 이해하기 어려운 몇 가지 구체적인 예는 도움이됩니다.

  5. from https://stackoverflow.com/questions/663254/why-doesnt-the-example-compile-aka-how-does-co-contra-and-in-variance-w by cc-by-sa and MIT license