我最近看一本小说《道诡异仙》,主角要去找正德寺找和尚的路上遇到了一个乞丐样的假和尚。主角说他是不个和尚,那假和尚说,和尚剃发念经他也剃发念经,和尚守戒吃斋他也守戒吃斋,怎么他就不是和尚了?
是的,我在前段时间的工作中也遇到同事这样的发问:两个对象之间为什么不能互相赋值?我说是因为两个对象类型不一样。他说这两个对象里面字段一模一样,甚至值都快要一样了,怎么还算不同一个类型?
因为我们的强类型是C#,在C#的类型系统里,是不是某个类型,需要打上类型认证的标记,这个标记是与生俱来的,是可以继承的,但是不可以后天修改的。除此之外,即使属性完全一致、方法完全一致,也不能算是相同类型,或是某个接口。门第之间如天涧鸿沟不可逾越。为此我们需要通过反射之类的方式创建诸如AutoMapper之类的方法来让他们之间可以互相转换。
而在Python之类的动态语言里,鸭子类型又是另一种常识了。鸭子类型说的是,如果有个动物长得像鸭子,叫起来像鸭子,走起来像鸭子,那它就是鸭子。
可惜的是动态语言是在运行时判断类型是否符合的,这会使得范式约束会不那么严格,无法提前检查出错误。那就不得不夸夸golang了,对golang来说类型是静态的,但是interface的检查又是基于接口声明的而非标签式的,使得我们能灵活的构建类型以满足各种使用时候的约束,而这些检查又是在编译时可以完成的。基于一些人生哲学上的立场原因,我是相当喜欢golang的这一特性了。