scala 协变和逆变
In this post, we are going to discuss about Scala Variance and it’s use cases.
在本文中,我们将讨论Scala Variance及其用例。
什么是方差? (What is Variance?)
Variance defines Inheritance relationships of Parameterized Types. Variance is all about Sub-Typing.
方差定义参数化类型的继承关系。 差异全都与子类型有关。
Please go through the following image to understand “What is Parameterized Type”.
请浏览下图以了解“什么是参数化类型”。
Here T is known as “Type Parameter” and List[T] is known as Generic.
在这里T被称为“类型参数”,而List [T]被称为泛型。
For List[T], if we use List[Int], List[AnyVal], etc. then these List[Int] and List[AnyVal] are known as “Parameterized Types”
对于List [T],如果我们使用List [Int],List [AnyVal]等,则这些List [Int]和List [AnyVal]被称为“参数化类型”
Variance defines Inheritance relationship between these Parameterized Types.
方差定义了这些参数化类型之间的继承关系。
Scala中的差异优势 (Advantage of Variance in Scala)
The main advantage of Scala Variance is:
Scala Variance的主要优点是:
Variance makes Scala collections more Type-Safe.差异使Scala集合更具类型安全性。 Variance gives more flexible development.差异使开发更加灵活。 Scala Variance gives us a technique to develop Reliable Applications.Scala Variance为我们提供了开发可靠应用程序的技术。
Scala中的方差类型 (Types of Variance in Scala)
Scala supports the following three kinds of Variance.
Scala支持以下三种方差。
Covariant协变 Invariant不变的 Contravariant逆变的
We will discuss these three variances in detail in coming sections.
我们将在接下来的部分中详细讨论这三个差异。
Scala中的协变 (Covariant in Scala)
If “S” is subtype of “T” then List[S] is is a subtype of List[T].
如果“ S”是“ T”的子类型,则List [S]是List [T]的子类型。
This kind of Inheritance Relationship between two Parameterized Types is known as “Covariant”
两种参数化类型之间的这种继承关系称为“协变”
Scala Covariance Syntax:-
To represent Covariance relationship between two Parameterized Types, Scala uses the following syntax:
Prefixing Type Parameter with “+” symbol defines Covariance in Scala.
Scala协方差语法:-
为了表示两个参数化类型之间的协方差关系,Scala使用以下语法:
带“ +”符号的前缀类型参数定义Scala中的协方差。
Here T is a Type Parameter and “+” symbol defines Scala Covariance.
这里T是类型参数,“ +”符号定义Scala协方差。
NOTE:-For simplicity reason, I’m using “List” here. However it may be any valid Scala Type like Set[+T], Ordered[+T] etc.
注意:-为简单起见,我在这里使用“列表”。 但是,它可以是任何有效的Scala类型,例如Set [+ T],Ordered [+ T]等。
Example:-
Write a Scala program to demo Scala Covariant SubTyping technique.
例:-
编写一个Scala程序来演示Scala协变量子类型技术。
class Animal[+T](val animial:T)class Dogclass Puppy extends Dogclass AnimalCarer(val dog:Animal[Dog])object ScalaCovarianceTest{def main(args: Array[String]) {val puppy = new Puppyval dog = new Dogval puppyAnimal:Animal[Puppy] = new Animal[Puppy](puppy)val dogAnimal:Animal[Dog] = new Animal[Dog](dog)val dogCarer = new AnimalCarer(dogAnimal)val puppyCarer = new AnimalCarer(puppyAnimal)println("Done.")}}
NOTE:-As Animal class is defined by using Variance Annotation i.e. “+T”, we can pass either dogAnimal or its subtype puppyAnimal to create a AnimalCarer object.
注意:由于Animal类是通过使用方差注释(即“ + T”)定义的,因此我们可以传递dogAnimal或其子类型puppyAnimal来创建AnimalCarer对象。
If we remove Variance Annotation in Animal class definition, like as shown below:
如果我们在动物类定义中删除方差注释,如下所示:
class Animal[T](val animial:T)// Remaining code is same as above.
It wont compile. We will get the following compilation error message:
它不会编译。 我们将收到以下编译错误消息:
Type mismatch, expected: Animal[Dog], found: Animal[Puppy]
To solve these kind of problems, we should use Scala Covariance.
为了解决这类问题,我们应该使用Scala协方差。
As per this example, we can say the following Scala Covariance:
根据此示例,我们可以说出以下Scala协方差:
“As Puppy is subtype of Dog, Animal[Puppy] is a subtype of Animal[Dog]. We can use Animal[Puppy] where we require Animal[Dog].” This is know as Scala Covariance.
“由于小狗是狗的亚型,所以动物[小狗]是动物[狗]的亚型。 我们可以在需要Animal [Dog]的地方使用Animal [Puppy]。” 这就是Scala协方差。
Scala中的变量 (Contravariant in Scala)
If “S” is subtype of “T” then List[T] is is a subtype of List[S].
如果“ S”是“ T”的子类型,则List [T]是List [S]的子类型。
This kind of Inheritance Relationship between two Parameterized Types is known as “Contravariant”
两种参数化类型之间的这种继承关系称为“Contravariant”
Scala Contravariant Syntax:
To represent Contravariant relationship between two Parameterized Types, Scala uses the following syntax:
Prefixing Type Parameter with “-” symbol defines Contravariant in Scala.
Scala变量语法:
为了表示两个参数化类型之间的相反关系,Scala使用以下语法:
带“-”符号的前缀类型参数定义Scala中的Contravariant。
Example:-
Write a Scala program to demo Scala Contravariant SubTyping technique.
例:-
编写一个Scala程序以演示Scala逆向子类型化技术。
abstract class Type [-T]{def typeName : Unit}class SuperType extends Type[AnyVal]{override def typeName: Unit = {println("SuperType")}}class SubType extends Type[Int]{override def typeName: Unit = {println("SubType")}}class TypeCarer{def display(t: Type[Int]){t.typeName}}object ScalaContravarianceTest {def main(args: Array[String]) {val superType = new SuperTypeval subType = new SubTypeval typeCarer = new TypeCarertypeCarer.display(subType)typeCarer.display(superType)}}
NOTE:-
As we define Contravariance in Type[-T], it works well. TypeCarer.display() is defined with Type[Int] i.e. SubType, but still it accepts Type[AnyVal] because Scala Contravariance subtyping.
注意:-
当我们在Type [-T]中定义Contravariance时,它运作良好。 TypeCarer.display()是用Type [Int](即SubType)定义的,但仍可以接受Type [AnyVal],因为Scala的Contravariance子类型化。
If we remove “-” definition in Type like “Type[T]”, then we will get compilation error.
如果我们在类型中删除“-”定义(如“ Type [T]”),则会出现编译错误。
Scala中的不变式 (Invariant in Scala)
If “S” is subtype of “T” then List[S] and List[T] don’t have Inheritance Relationship or Sub-Typing. That means both are unrelated.
如果“ S”是“ T”的子类型,则List [S]和List [T]没有继承关系或子类型。 这意味着两者无关。
This kind of Relationship between two Parameterized Types is known as “Invariant or Non-Variant”
两种参数化类型之间的这种关系称为“不变或无变量”
In Scala, by default Generic Types have Non-Variant relationship. If we define Parameterized Types without using “+’ or “-” symbols, then they are known as Invariants.
在Scala中,默认情况下,泛型类型具有Non-Variant关系。 如果我们在不使用“ +”或“-”符号的情况下定义参数化类型,则它们被称为不变式。
什么是Scala中的方差注释? (What is Variance Annotation in Scala?)
Variance Annotation means defining “+” or “-” before Type Parameters.
差异注释表示在类型参数之前定义“ +”或“-”。
Example:-
+T and – T are know as Variance Annotations in Scala.
例:-
+ T和– T在Scala中称为方差注释。
Scala方差摘要 (Scala Variance Summary)
In this section, we are going to summarize all 3 concepts we have discussed about Scala Variance Types in above sections.
在本节中,我们将总结在以上各节中讨论过的有关Scala方差类型的所有3个概念。
That’s it all about Scala Variance. We will discuss some more Scala concepts in my coming posts.
这就是Scala Variance的全部内容。 我们将在我的后续文章中讨论更多Scala概念。
Please drop me a comment if you like my post or have any issues/suggestions.
如果您喜欢我的帖子或有任何问题/建议,请给我评论。
翻译自: /9585/scala-variances-covariant-invariant-contravariant
scala 协变和逆变