Scala 协变 和 逆变 二

协变和逆变主要是用来解决参数化类型的泛化问题。由于参数化类型的参数(参数类型)是可变的,当两个参数化类型的参数是继承关系(可泛化),那被参数化的类型是否也可以泛化呢?Java中这种情况下是不可泛化的,然而Scala提供了三个选择,即协变、逆变和非变。下面说一下三种情况的含义,首先假设有参数化特征Queue,那它可以有如下三种定义。

1)trait Queue[T] {}

这是非变情况。这种情况下,当类型S是类型A的子类型,则Queue[S]不可认为是Queue[A]的子类型或父类型,这种情况是和Java一样的。

2)trait Queue[+T] {}

这是协变情况。这种情况下,当类型S是类型A的子类型,则Queue[S]也可以认为是Queue[A}的子类型,即Queue[S]可以泛化为Queue[A]也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变。 

3)trait Queue[-T] {}

这是逆变情况。这种情况下,当类型S是类型A的子类型,则Queue[A]反过来可以认为是Queue[S}的子类型。也就是被参数化类型的泛化方向与参数类型的方向是相反的,所以称为逆变。 

时间: 2024-10-13 05:04:23

Scala 协变 和 逆变 二的相关文章

Scala 协变 和 逆变

在Scala(以及其他许多编程语言)中,函数也是对象,可以使用.定义其他对象的地方,也可以使用.定义函数.Scala中的函数,具有apply方法的类的实例,就可以当做函数来使用.其中apply接受的参数就是函数的参数,而apply的返回值就是函数的返回值. 首先给出一个接受一个参数的函数的泛型定义. trait Function1[-T, +U] {   def apply(x: T): U } 这种函数接受一个参数,参数类型为泛型类型T,返回类型为泛型类型U.和其他支持泛型的语言一样,实际定义

Scala类型参数中协变(+)、逆变(-)、类型上界(<:)和类型下界(>:)的使用

转自:http://fineqtbull.iteye.com/blog/477994#bc2364938 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的使用方法和原理,自己虽然也刚学不久,在主要调查了<Programing in Scala>的19章后,试着在下面做一个总结.如有错误之处还请各位指正. 先说说协变和逆变(实际上还有非变).协变和逆变主要是用来解决参数化类型的泛化问题.由于参数化类型的参数(参数类型)是可变的,当两个参数化类型的参数是继承关系

Scala中的协变,逆变,上界,下界等

Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 View Bound <% Context Bound 参考文档 Scala中的协变逆变和Java中的协变逆变不一样,看起来更复杂. 本文对Scala中的这些概念做一总结.首先看几个概念: covariant 协变.使你能够使用比原始指定的类型的子类 Contravariance 逆变.使你能够使

scala学习笔记-类型参数中协变(+)、逆变(-)、类型上界(&lt;:)和类型下界(&gt;:)的使用

转载自  fineqtbull   http://fineqtbull.iteye.com/blog/477994 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的使用方法和原理,自己虽然也刚学不久,在主要调查了<Programing in Scala>的19章后,试着在下面做一个总结.如有错误之处还请各位指正. 先说说协变和逆变(实际上还有非变).协变和逆变主要是用来解决参数化类型的泛化问题.由于参数化类型的参数(参数类型)是可变的,当两个参数化类型的参数

(转)Scala中协变(+)、逆变(-)、上界(&lt;:)、下界(&gt;:)简单介绍

看源码的时候看到: trait ExtensionId[T <: Extension] { 没见过这个符号啊<: Scala上界(<:)和下界(>:) 1) U >: T 这是类型下界的定义,也就是U必须是类型T的父类(或本身,自己也可以认为是自己的父类). 2) S <: T 这是类型上界的定义,也就是S必须是类型T的子类(或本身,自己也可以认为是自己的子类). 然后scala中的泛型符号是[T],而不是Java中的<T>. 对于一个带类型参数的类型,比如

Scala中的协变(+),逆变(-),上界(&lt;:),下界(&gt;:)

对于一个带类型参数的类型,比如 List[T],如果对A及其子类型B,满足 List[B]也符合 List[A]的子类型,那么就称为covariance(协变) ,如果 List[A]是 List[B]的子类型,即与原来的父子关系正相反,则称为contravariance(逆变). 如果一个类型支持协变或逆变,则称这个类型为variance(翻译为可变的或变型),否则称为invariant(不可变的)   在Java里,泛型类型都是invariant,比如 List<String> 并不是 L

Scala入门到精通——第二十一节 类型参数(三)-协变与逆变

作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 协变 逆变 类型通匹符 1. 协变 协变定义形式如:trait List[+T] {} .当类型S是类型A的子类型时,则List[S]也可以认为是List[A}的子类型,即List[S]可以泛化为List[A].也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变(covariance). 图1 协变示意图 为方便大家理解,我们先分析java语言中为什么不存在协变及下一

Scala中的类、接口及协变和逆变

 4.   OOP 4.1.     类class 4.1.1.  定义 例子1: class User { var name = "anonymous" var age:Int = _ val country = "china" def email = name + "@mail" } 使用: val u = new User // var定义的属性可读可写 u.name = "qh"; u.age = 30 print

协变和逆变

具体可以参考:<Effective Java>PECS 原则 (producser-extends, consumer-super) G[+A]类似一个生产者,提供数据.(大部分情况下称G为容器类型)G[-A] 是一个消费者,主要用来消费数据.(如上的 Equiv[-A] (其实就是个A => Boolean的函数,即Function1[-A, Boolean])) 同理函数的参数为何声明为逆变,返回值为协变就好理解了同理class G[+A]{def fun[B >: A](x: