动态和静态类型

一个机器或语言是用来计算的,根据计算机模型的定义,其操作的是存储器里的数据,就现在流行的用二进制实现的计算机中(曾出现过三进制计算机),数据本质都是0和1,但机器毕竟是为人服务的,解决的是现实问题,它操作的数据需要有现实的含义,所以基本上所有语言都有类型系统,即便是汇编和机器语言,也有整数和浮点的区别  

类型系统是很复杂的理论,值得用一本厚书来写,好点的资料有《类型与程序设计语言》,但我没看懂,因为太抽象了。其实如果想实际做东西,也不用搞很深的理论,了解一些常见的即可,比如类型的动静态的区别  

类型的动态和静态,一般是指变量和类似变量(属性、数组元素等)的类型是否确定,比如说,C语言就是静态类型的,一个变量必须定以后才能使用,而且使用时,它的值必须按照它的类型来参与运算,比如int64_t和double都是8字节,但同样的数据内容,表示的数字可能完全不同,一个指针虽然以uint的方式存储,但含义也是不同的,做赋值操作时,如果被赋值的左值的类型和赋予的值得类型不同,需要进行转换,如果不符合语言本身规定的转换规则(一般都很受限,比如只能short赋值给int,子类对象地址赋值给父类指针等,反过来不行),就会编译报错  

静态类型的优点在于,很多东西在静态编译阶段就能确定了,比方说我们定义了一个结构体s,那么在对s取属性的时候,就可以根据地址偏移来进行,因为s的类型的各属性的布局是确定好的,这就提高了程序运行速度,也方便做各种代码优化,比如一个对象A a,调用a.f()的时候,就可以静态确定调用的是哪个函数,视情况inline;另外,程序员写代码的时候,编译器可以做更严格的检查,防止出现一些非预期的错误  

动态类型就相反,语言的变量和类似变量没有自己的类型,这并不是说这种语言没有类型,数据都是有类型的,只是变量可以引用任何对象,使用的时候以当前的值为准,比如:  
a = 123 
print a 
a = "hello" 
print a 

a只是一个名字,两次输出的时候,会根据a当时关联的具体的值来判断如何做  

因为变量没有类型,所以动态类型语言一般都省掉了声明过程,这样代码写起来会很省事,但相对的静态编译就检查不出太多错误,一个变量没有定义就使用这种错误都会在运行时抛出,不过,这个问题不仅是动态类型的问题,跟整体的动态性也有很大关系,后面再专门论述  

静态类型的实现,一般来说只要实现基本类型即可(整数,浮点数,地址指针等),因为结构体、类等高级类型说到底还是由基本类型组成的,这些东西在编译后,一般都消失无踪,运行时只知道从xx位置拿一个xx数据,做数学运算,然后写回xx地址  

动态类型的话,以python为例,一般是采用面向对象的方式实现,所有的数据都以对象的形式体现,并且继承于同一个基类object,因此,python代码可以认为所有变量的类型都是object,因为大家都是,所以类型定义就可以省了,比如  
def f(a, b): 
    return a + b 
print f(1, 2) 
print f("hello", "world") 

换成静态类型的伪代码大概就是:  
object f(object a, object b) 
{ 
    return a.add(b); 
} 
put(f(Int(1), Int(2)).toString()) 
put(f(Str("hello"), Str("world")).toString()) 

实际上,java虽然是静态类型语言,但也实现了这种模式,如果不考虑int,long等基础类型,实际上所有的类型都是继承于Object,但是如果上面代码改成java代码,就无法运行,因为Object本身没有add之类的方法,所以就算传入的类型有这个方法,但是函数f本身会编译失败,之前说了,我的目标是设计一个类似python的动态类型语言,然后转成java代码,对象继承这个特性是连接这两种语言很重要的一环  

个人经验,喜欢动态类型的人居多,这还是有道理的,因为用动态类型语言写代码,可以把更多精力放在“做什么”上,而不用考虑太多细节的“怎么做”,python只需要写一个[],然后往里面塞{},java可能就要写Vector<HashMap<String,Integer>>这种折腾人的东西(java还没有运算符重载),于是再发展,就有了鸭子类型的概念  

鸭子类型来自于这样一个说法,假如一个动物各方面都跟鸭子一样,那么它就是一只鸭子,或者说我们把它当鸭子对待,没有任何问题,哪怕它实际是一个钢铁做的机器。不关注是什么,只看重怎么用  

python就是鸭子类型语言,例如这个代码:  
def f(a): 
    a.g(1,2,3) 

f并不关心传入的a究竟是什么,只要a有一个方法g并且g能接受三个整数参数,就可以了。python中只要一个对象实现了运算符()的重载,就能像函数或类一样调用,甚至只要你把一个对象“伪装”得跟一个类一样,就可以直接定义一个继承自它的类  

其实静态类型语言也可以实现类似鸭子类型,不过这个后面再说了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态语言静态类语言是两种不同的编程语言动态语言是指在运行进行类检查的编程语言。这意味着变量的类是在运行确定的,可以在程序中自由地改变变量的类动态语言通常具有更灵活的语法和更少的类限制,使得编写代码更加简洁和灵活。常见的动态语言有Python和JavaScript。 静态类语言是指在编译进行类检查的编程语言。这意味着变量的类在编写代码就需要确定,并且不能随意改变其类静态类语言需要在编写代码显式地声明变量的类,并且在编译会进行类检查,以确保类的一致性和正确性。常见的静态类语言有C++和Java。 区别: 1. 类检查:动态语言在运行进行类检查,而静态类语言在编译进行类检查。 2. 变量声明:动态语言不需要显式声明变量的类,而静态类语言需要在编写代码显式地声明变量的类。 3. 灵活性:动态语言具有更大的灵活性,可以在运行改变变量的类,而静态类语言的变量类在编译就需要确定,无法随意改变。 4. 错误检查:静态类语言在编译可以检测到一些类相关的错误,而动态语言只能在运行才能检测到类错误。 需要注意的是,动态语言静态类语言各有优缺点,并不是绝对好坏之分,选择使用哪种类编程语言要根据具体的需求和场景来决定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值