草庐IT

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

躺柒 2023-03-28 原文

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. 会绕过类型检查立即把该值用作其他任何类型的值

有关读编程与类型系统笔记07_子类型的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  3. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  6. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  7. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  8. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  9. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  10. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

随机推荐