最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

读编程与类型系统笔记07_子类型

来源:博客园


(资料图)

1.子类型

1.1.在期望类型T的实例的任何地方,都可以安全地使用类型S的实例,则类型S是类型T的子类型

1.1.1.里氏替换原则(Liskov substitution principle)

2.名义子类型

2.1.明确指定

2.2.显式声明一个类型是另一个类型的子类型

2.3.大部分主流编程语言采用的方式

2.3.1.Java

2.3.2.C#

2.4.TypeScript通过使用unique symbol可以模拟名义子类型

3.结构子类型

3.1.类型具有相同的结构

3.2.不需要显式声明子类型关系

3.3.一个类型的结构与另一个类型相似(具有相同的成员,可能还有额外的成员),自动被视为后者的子类型

3.4.TypeScript使用结构子类型

3.5.即使类型不在我们的控制范围内,我们在类型之间仍然能建立关系

3.5.1.例如:我们不能修改的来自外部库的一个类型

4.极端情况

4.1.顶层类型

4.1.1.把任何东西赋值给它的类型

4.1.1.1.用来存储任何东西

4.1.1.2.C#的Object

4.1.1.3.TypeScript的unknown

4.1.1.3.1.null的类型是null
4.1.1.3.2.undefined的类型是undefined
4.1.1.3.3.Object
4.1.1.3.4.三者和类型即unknown
4.1.1.3.4.1.Object | null |undefined
4.1.1.3.5.只有当我们确认一个值具有某个类型时,才能把该值用作该类型
4.1.1.3.5.1.C#提供了is关键字
4.1.1.3.5.2.Java则提供了instanceof

4.1.2.其他任何类型的父类型

4.1.3.位于子类型层次结构的顶端

4.2.底层类型

4.2.1.可以赋值给任何东西的类型

4.2.1.1.没有某种类型的实例可用

4.2.1.2.TypeScript的never

4.2.2.其他任何类型的子类型

4.2.3.位于子类型层次结构的底端

4.2.4.始终是一个空类型:这是我们不能为其创建实际值的类型

4.2.5.允许我们假装有任何类型的一个值,即使我们并不能生成这个值

4.2.6.很少有主流语言提供底层类型

4.2.6.1.使一个类型成为空类型,但不能使其成为底层类型

4.2.6.2.除非在编译器中实现,否则我们无法自定义底层类型

5.和类型

5.1.父类型比子类型的类型更多

5.1.1.例如:Triangle | Square是Triangle | Square | Circle的子类型

5.2.Variant能够封装几个类型中某个类型的值,但是它本身不是其中任何一个类型

6.可变性

6.1.协变性

6.1.1.一个类型保留其底层类型的子类型关系

6.1.2.数组具有协变性,因为它保留了子类型关系

6.1.3.当处理集合(如LinkedList)时,不同的语言具有不同的行为

6.1.3.1.在C#中,必须通过声明接口并使用out关键字(ILinkedList),显式指出一个类型(如LinkedList)的协变

6.1.4.函数的返回类型具有协变性

6.2.逆变性

6.2.1.一个类型颠倒了其底层类型的子类型关系

6.2.2.大部分编程语言中,函数的实参是逆变的

6.2.2.1.TypeScript是一个例外

6.2.2.1.1.故意做出的设计决策

6.3.双变性

6.3.1.类型的底层类型的子类型关系决定了它们互为子类型

6.3.2.在TypeScript中函数实参的双变性可能导致错误的代码通过编译

6.4.不变性

6.4.1.一个类型不考虑其底层类型的子类型关系

6.4.2.C#中的List具有不变性

7.any类型

7.1.可以把任何值赋值给any

7.2.可以把any值绕过类型检查赋值给其他任何类型

7.3.会绕过类型检查立即把该值用作其他任何类型的值

关键词: 层次结构 编程语言