scala读书学习笔记009

1、一个类可能并没有定义或继承任何var变量,但它依然是可变的,因为它将方法调用转发到了其他带有可变状态的对象上。反过来也是有可能的:一个类可能包含了var但却是纯函数式的。例如某个类可能为了优化性能将开销巨大的操作结果缓存在字段中。

2、在Scala中,每一个非私有的var成员都隐式地定义了对应的getter和setter方法。不过,这些getter方法和setter方法的命名跟Java的习惯不一样。var x的getter方法只是命名为“x”,而它的setter方法命名为“x_=”。

3、scala总是将变量解读为setter和getter方法的这个做法,让我们在不需要特殊语法的情况下获得了跟C#属性一样的能力。

4、可变状态和高阶函数。可变状态用于模拟那些状态随时间改变的物理实体。而高阶函数在模拟框架中用来在指定的模拟时间执行动作。高阶函数还在电路模拟中被当作触发器(trigger)使用,它们跟状态变化关联起来。

5、类型参数化让我们能够编写泛型的类和特质。例如,集(set)是泛型的,接收一个类型参数:定义为Set[T]。这样,具体的集的实例可以是Set[String]、Set[Int]等,不过它必须是某种类型的集。与Java不同,Scala并不允许原生类型,Scala要求我们给出类型参数。型变定义了参数化类型的继承关系,以Set[String]为例,型变定义了它是不是Set[AnyRef]的子类型。

6、纯函数式队列还跟列表有一些相似,它们都被称作完全持久化(fully persistent)的数据结构,在经过扩展或修改之后,老版本将继续保持可用。它们都支持head和tail操作。不过列表通常用::操作在头部扩展,而队列在尾部扩展,用的是enqueue方法。

7、如何实现才是高效的呢?在最理想的情况下,一个函数式(不可变)的队列跟一个指令式(可变)的队列相比不应该有从根本上更高的额外开销。也就是说,所有三个操作,head、tail和enqueue操作都应该以常量时间完成。实现函数式队列的一种简单方式是用列表来作为表现类型。这样一来head和tail都只是简单地翻译成列表中相同的操作,而enqueue则通过列表拼接来实现。

8、类名和参数之间的private修饰符表示Queue的构造方法是私有的:它只能从类本身及其伴生对象访问。类名Queue依然是公有的,因此可以把它当作类型来使用,但不能调用其构造方法:
私有构造方法和私有成员只是隐藏类的初始化和内部表现形式的一种方式。另一种更激进的方式是隐藏类本身,并且只暴露一个反映类的公有接口的特质。

9、Queue是一个特质,而Queue[String]是一个类型。Queue也被称作类型构造方法(type constructor),因为我们可以通过指定类型参数来构造一个类型(这跟通过指定值参数来构造对象实例的普通构造方法的道理是一样的)。类型构造方法Queue能够“生成”成组的类型,包括Queue[Int]、Queue[String]和Queue[AnyRef]。也可以说Queue是一个泛型(generic)的特质(接收类型参数的类和特质是“泛型”的,但它们生成的类型是“参数化”的,而不是泛型的)。“泛型”的意思是我们用一个泛化的类或特质来定义许许多多具体的类型。

10、如果S是类型T的子类型,那么Queue[S]应不应该被当作Queue[T]的子类型?如果是,可以说Queue特质在类型参数T上是协变的(convariant)(或者说“灵活的”)。由于它只有一个类型参数,也可以简单地说Queue是协变的。协变的Queue意味着我们可以传入一个Queue[String]到前面的doesCompile方法,这个方法接收的是类型为Queue[AnyRef]的值参数。
我们可以修改Queue类定义的第一行来要求队列的子类型关系是协变(灵活)的:
在类型形参前面加上+表示子类型关系在这个参数上是协变(灵活)的。通过这个字符,我们告诉Scala我们要的效果是,Queue[String]是Queue[AnyRef]的子类型。编译器会检查Queue的定义符合这种子类型关系的要求。除了+,还有-可以作为前缀,表示逆变(contravariance)的子类型关系。如果Queue的定义是下面这个样子:
那么如果T是类型S的子类型,则表示Queue[S]是Queue[T]的子类型(这对于队列的例子而言很出人意料!)。类型参数是协变的、逆变的还是不变的,被称作类型参数的型变(variance)。可以放在类型参数旁边的+和-被称作型变注解(variance annotation)。

11、Java在运行时会保存数组的元素类型。每当数组元素被更新,都会检查新元素值是否满足保存下来的类型要求。如果新元素值不是这个类型的实例,就会抛出ArrayStoreException。

12、所有对类型可靠性的违背都涉及可被重新赋值的字段或数组元素。与此相对应地,纯函数式实现的队列看上去是协变的不错的候选人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值