Development Tip

Scala에서 A <: B와 + B의 차이점은 무엇입니까?

yourdevel 2020. 11. 12. 20:28
반응형

Scala에서 A <: B와 + B의 차이점은 무엇입니까?


차이점은 무엇입니까

[A <: B]

[+B]

스칼라에서?


Q[A <: B]클래스는 것을 의미 Q모든 클래스 취할 수 A의 서브 클래스입니다 B.

Q[+B]수단 Q취할 수 있는 경우 클래스 만 A의 서브 클래스입니다 B다음은, Q[A]의 서브 클래스로 간주됩니다 Q[B].

Q[+A <: B]즉, 클래스 QB하위 클래스 관계를 전파 할뿐만 아니라 하위 클래스 만 사용할 수 있습니다 .

첫 번째는 일반적인 작업을 수행하려는 경우 유용하지만 .NET의 특정 메서드 집합에 의존해야합니다 B. 당신이있는 경우 예를 들어, Output로 수업을 toFile하는 방법, 당신은에 전달 될 수있는 모든 클래스에서 그 방법을 사용할 수 있습니다 Q.

두 번째는 원래 클래스와 동일한 방식으로 작동하는 컬렉션을 만들 때 유용합니다. 당신이 가져 가서 B서브 클래스 A를 만든다면, 당신 은 예상되는 A곳 어디든 전달할 수 있습니다 B. 당신이 걸릴하지만 수집B, Q[B], 당신이 항상에서 전달할 수 있다는 사실 Q[A]대신? 일반적으로 아니오; 이것이 잘못된 일인 경우가 있습니다. 그러나 이것은 +B(공분산; 공변량 Q- B'하위 클래스'상속 관계 와 함께 따라 옴) 을 사용하여 옳은 일이라고 말할 수 있습니다 .


Rex Kerr의 훌륭한 답변 을 더 많은 예제 로 확장하고 싶습니다 . 4 개의 클래스가 있다고 가정 해 보겠습니다.

 class Animal {}
 class Dog extends Animal {}

 class Car {}
 class SportsCar extends Car {}

분산부터 시작하겠습니다.

 case class List[+B](elements: B*) {} // simplification; covariance like in original List

 val animals: List[Animal] = List( new Dog(), new Animal() )
 val cars: List[Car] = List ( new Car(), new SportsCar() )

보시다시피 List는 Animals 또는 Cars를 포함하는지 상관하지 않습니다 . List 개발자는 예를 들어 Cars 만 Lists에 들어갈 수 있다고 강제하지 않았습니다.

추가적으로 :

case class Shelter(animals: List[Animal]) {}

val animalShelter: Shelter = Shelter( List(new Animal()): List[Animal] )
val dogShelter: Shelter = Shelter( List(new Dog()): List[Dog] )

함수에 List[Animal]매개 변수가 필요한 경우 List[Dog]대신 함수에 인수로를 전달할 수도 있습니다 . List의 공분산으로 인해 List[Dog] 의 하위 클래스로 간주됩니다 List[Animal] . List가 변하지 않으면 작동하지 않습니다.

이제 유형 경계에 대해 설명합니다.

case class Barn[A <: Animal](animals: A*) {}

val animalBarn: Barn[Animal] = Barn( new Dog(), new Animal() )
val carBarn = Barn( new SportsCar() )
/* 
error: inferred type arguments [SportsCar] do not conform to method apply's type parameter bounds [A <: Animal]
    val carBarn = Barn(new SportsCar())
                 ^
*/

보시다시피 Barn은 동물 전용 컬렉션 입니다. 여기에 차는 허용되지 않습니다.


내 이해를 위해 :


첫 번째는 매개 변수 유형 경계이며, 우리의 경우에는 B (또는 B 자체)의 하위 유형 인 "유형 매개 변수 A"가있는 상위 및 하위 유형 경계가 있습니다.


두 번째는 클래스 정의에 대한 Variance Annotation입니다. 우리의 경우 B의 공분산 서브 클래 싱입니다.


Scala: + Java: ? extends T Covariant subclassing

Scala: - Java: ? super T Contravariant subclassing


I found this blog post while researching this question. Gives an even deeper explanation of Scala variance including its theoretical basis in Category Theory

http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/

참고URL : https://stackoverflow.com/questions/4531455/whats-the-difference-between-ab-and-b-in-scala

반응형