类型的重要性
类型是什么?
人类思考的一种方式
类型的本质是在思考:“什么是什么”。我们在日常生活中,会对各种东西进行分类,比如:
- 🐶:狗是动物类
- 🍅:番茄是蔬菜,是植物
:我们的“猪厂学习鸡”,属于飞禽类,当然也属于动物类
- ...
那么,人们对日常生活中的各种生物、非生物进行分类,目的是什么呢?人们对身边的事物进行分类,主要是为了方便人们“认知世界”。因为这个世界上的事物实在太多了,如果他们各自都杂乱无章,毫无联系,那么我们几乎不可能将这个世界探索明白。
当人们学会对具有相同或相似特性的事物进行分类之后,发现我们需要记得东西急剧减少,还能够通过某一个特性很快的联想到其他的事物,比如说:人会学习,那么还有什么会学习呢?
- 大猩猩会通过学习掌握工具的使用
- 老鹰会通过学习学会在蓝天中翱翔
- 老虎会通过学习学会如何扑杀猎物
- 学习鸡会通过学习学会分身术,为更多猪厂学习爱好者带来更多精彩活动
- ...
这样,我们就通过“学习”这个公用的特性找到了彼此看似毫无关联的事物之间的联系。
所以说,类型是人类思考的一种方式,是人类认识世界探索世界的手段。
程序世界中的类型
当然,在程序世界当中,我们的分类方式可能与现实世界不太一样,但根本目的都是一样的,就是:抽象一个事物的共性。例如:
所有的动物都可以走路,无论猫、狗、人、还是学习鸡,那么我们就可以抽离出这一共性,称具备这种能力的生物是可行走的,也就是具备行走能力的。这样,我们就将所有的具备行走能力的事物都归为一类了。
需要注意的是,在编程领域当中:类型思维在函数式编程与面向对象编程中都是高度统一的。
还是上面的示例,分别用函数式和面向对象的方式描述人可以行走:
- 函数式:人是
Moveable<T>的 - 面向对象:对象人拥有
move方法
当我们在思考一个程序的类型的时候,实际上就是在思考一个系统的架构了。当你将系统中的每一个事物都逐一分类好了,并用合适的类型去处理,那么你已经完成了系统架构的很大一部分工作了。
程序中如何进行类型的思考
-
string类型和number类型的数据都是可以被比较的,如:1===1、'kiner'==='kiner',因此,他们都是Comparable的,即可比较的。 -
Array是可枚举的,所以是Enumerable -
在
React当中,刚开始只有类组件,即ComponentClass<P>,而后来多了函数式组件,即:FunctionComponent<P>,因此,React的的组件类型也有刚开始单纯的ComponentClass<P>演进成了:type ComponentType<P> = ComponentClass<P> | FunctionComponent<P>;可以看出,
React的演进过程也正是React在不断的尝试以更全面的描述组件的过程,是React团队对组件认知的一个提升。
通过类型的演进使系统不断进化
我们在不断的对系统内各种模块类型的演进的同时,我们的系统也得以不断的进化与完善,这也就是我们不断完善系统架构的非常重要的一步。这就是“领域驱动开发最核心的理念”。
我经常跟一些初次接触Typescript的同学说:“拿到需求,别急着写功能,先定义系统的类型、写接口、写枚举,当你把这些东西慢慢完成之后,你会对你要做的需求有前所未有的的认识与了解。”
程序中错误检查的利器
每一次的类型检查都可能帮助减少一个错误。
function sayHello(name: string) {
console.log(`hello, ${name}`);
}
// 类型“number”的参数不能赋给类型“string”的参数。
sayHello(11);
或许有同学觉得,这也不过如此嘛,真的能给系统减少错误带来那么大的提升吗?
我们来举个例子:假如说上述的sayHello是在某个系统中的高频调用函数,我们没调用一次这个函数都会进行类型检查,每次检查有10%的概率找到bug,那么,如果这个函数被调用了10次呢?
P = (1 - 0.1)^10 = 65.13%
也就是说,如果该函数被调用了10次,那么类型检查能帮我们找到问题的概率是65.13%。那如果我们系统里每一个函数都有类型检查呢?那我们找到问题的概率是不是呈几何倍数上升了。
一个设计的好的系统可以做编译时检查,通过既上线,帮助我们减少很多Bug。
总结
总结一下:类型是人类思考的一种方式,一个好的程序设计能够帮助人更好的思考。类型能够帮助你发现系统中的错误。能够帮助系统不断地演进。