什么是编程语⾔的强类型,弱类型
给你来个例⼦把弱类型语⾔vbs: a=1 b=a+"1"+"a" //结果是11a,这⾥ a 成了字符串 c=a+1 //结果是2 ,这⾥a则是数字型强类型语⾔:c# int a=2 string b=a.ToString()+"1"+"a" int
c=a+1 看到了吗?区分⼤⼩写,需要实现申明类型外,⼀个重要的区别是,弱类型的语⾔的东西没有明显的类型,他能随着环境的不同,⾃动变换类型⽽强类型则没这样的规定,不同类型间的操作有严格定义,只有相同类型的变量才能操作,虽然系统也有⼀定的默认转换,当绝没有弱类型那么随便 ps:弱类型代码简单,但因为变量没有确定的类型,所以容易出错!强类型代码复杂(⽐如:转换⽇期显⽰格式 (Datetime("2007-1-1 08:08:08")).ToString("yyyy-MM-dd"),呵呵你可以看到这种写法相当⿇烦),但因为有严格定义所以不容易出错编译型和解释型
我们先看看编译型,其实它和汇编语⾔是⼀样的:也是有⼀个负责翻译的程序来对我们的源代码进⾏转换,⽣成相对应的可执⾏代码。这个过程说得专业⼀点,就称为编译(Compile),⽽负责编译的程序⾃然就称为编译器(Compiler)。如果我们写的程序代码都包含在⼀个源⽂件中,那么通常编译之后就会直接⽣成⼀个可执⾏⽂件,我们就可以直接运⾏了。但对于⼀个⽐较复杂的项⽬,为了⽅便管理,我们通常把代码分散在各个源⽂件中,作为不同的模块来组织。这时编译各个⽂件时就会⽣成⽬标⽂件(Object
file)⽽不是前⾯说的可执⾏⽂件。⼀般⼀个源⽂件的编译都会对应⼀个⽬标⽂件。这些⽬标⽂件⾥的内容基本上已经是可执⾏代码了,但由于只是整个项⽬的⼀部分,所以我们还不能直接运⾏。待所有的源⽂件的编译都⼤功告成,我们就可以最后把这些半成品的⽬标⽂件“打包”成⼀个可执⾏⽂件了,这个⼯作由另⼀个程序负责完成,由于此过程好像是把包含可执⾏代码的⽬标⽂件连接装配起来,所以⼜称为链接(Link),⽽负责链接的程序就叫……就叫链接程序(Linker)。链接程序除了链接⽬标⽂件外,可能还有各种资源,像图标⽂件啊、声⾳⽂件啊什么的,还要负责去除⽬标⽂件之间的冗余重复代码,等等,所以……也是挺累的。链接完成之后,⼀般就可以得到我们想要的可执⾏⽂件了。
上⾯我们⼤概地介绍了编译型语⾔的特点,现在再看看解释型。噢,从字⾯上看,“编译”和“解释”的确都有“翻译”的意思,它们的区别则在于翻译的时机安排不⼤⼀样。打个⽐⽅:假如你打算阅读⼀本外⽂书,⽽你不知道这门外语,那么你可以⼀名翻译,给他⾜够的时间让他从头到尾把整本书翻译好,然后把书的母语版交给你阅读;或者,你也⽴刻让这名翻译辅助你阅读,让他⼀句⼀句给你翻译,如果你想往回看某个章节,他也得重新给你翻译。
两种⽅式,前者就相当于我们刚才所说的编译型:⼀次把所有的代码转换成机器语⾔,然后写成可执⾏⽂件;⽽后者就相当于我们要说的解释型:在程序运⾏的前⼀刻,还只有源程序⽽没有可执⾏程序;⽽程序每执⾏到源程序的某⼀条指令,则会有⼀个称之为解释程序的外壳程序将源代码转换成⼆进制代码以供执⾏,总⾔之,就是不断地解释、执⾏、解释、执⾏……所以,解释型程序是离不开解
释程序的。像早期的BASIC就是⼀门经典的解释型语⾔,要执⾏BASIC程序,就得进⼊BASIC环境,然后才能加载程序源⽂件、运⾏。解释型程序中,由于程序总是以源代码的形式出现,因此只要有相应的解释器,移植⼏乎不成问题。编译型程序虽然源代码也可以移植,但前提是必须针对不同的系统分别进⾏编译,对于复杂的⼯程来说,的确是⼀件不⼩的时间消耗,况且很可能⼀些细节的地⽅还是要修改源代码。⽽且,解释型程序省却了编译的步骤,修改调试也⾮常⽅便,编辑完毕之后即可⽴即运⾏,不必像编译型程序⼀样每次进⾏⼩⼩改动都要耐⼼等待漫长的Compiling…Linking…这样的编译链接过程。不过凡事有利有弊,由于解释型程序是将编译的过程放到执⾏过程中,这就决定了解释型程序注定要⽐编译型慢上⼀⼤截,像⼏百倍的速度差距也是不⾜为奇的。
编译型与解释型,两者各有利弊。前者由于程序执⾏速度快,同等条件下对系统要求较低,因此像开发操作系统、⼤型应⽤程序、数据库系统等时都采⽤它,像C/C++、Pascal/Object Pascal(Delphi)、VB等基本都可视为编译语⾔,⽽⼀些⽹页脚本、服务器脚本及辅助开发接⼝这样的对速度要求不⾼、对不同系统平台间的兼容性有⼀定要求的程序则通常使⽤解释性语⾔,如Java、JavaScript、VBScript、Perl、Python等等。
但既然编译型与解释型各有优缺点⼜相互对⽴,所以⼀批新兴的语⾔都有把两者折衷起来的趋势,例如Java语⾔虽然⽐较接近解释型语⾔的特征,但在执⾏之前已经预先进⾏⼀次预编译,⽣成的代码是介于机器码和Java源代码之间的中介代码,运⾏的时候则由JVM(Java的虚拟机平台,可视为解释器)
解释执⾏。它既保留了源代码的⾼抽象、可移植的特点,⼜已经完成了对源代码的⼤部分预编译⼯作,所以执⾏起来⽐“纯解释型”程序要快许多。⽽像VB6(或者以前版本)、C#这样的语⾔,虽然表⾯上看⽣成的是.exe可执⾏程序⽂件,但VB6编译之后实际⽣成的也是⼀种中介码,只不过编译器在前⾯安插了⼀段⾃动调⽤某个外部解释器的代码(该解释程序独⽴于⽤户编写的程序,存放于系统的某个DLL⽂件中,所有以VB6编译⽣成的可执⾏程序都要⽤到它),以解释执⾏实际的程序体。C#(以及其它的语⾔编译器)则是⽣成⽬标代码,实际执⾏时则由解释系统(就像JVM⼀样,也是⼀个虚拟机平台)进⾏执⾏。当然⽬标代码已经相当“低级”,⽐较接近机器语⾔了,所以仍将其视为编译语⾔,⽽且其可移植程度也没有Java号称的这么强⼤,Java号称是“⼀次编译,到处执⾏”,⽽则是“⼀次编码,到处编译”。呵呵,当然这些都是题外话了。总之,随着设计技术与硬件的不断发展,编译型与解释型两种⽅式的界限正在不断变得模糊。
动态语⾔和静态语⾔
通常我们所说的动态语⾔、静态语⾔是指动态类型语⾔和静态类型语⾔。
(1)动态类型语⾔:动态类型语⾔是指在运⾏期间才去做数据类型检查的语⾔,也就是说,在⽤动态类型的语⾔编程时,永远也不⽤给任何变量指定数据类型,该语⾔会在你第⼀次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是⼀种典型的动态类型语⾔,其他的各种脚本语⾔如VBScript也多少属于动态类型语⾔。
(2)静态类型语⾔:静态类型语⾔与动态类型语⾔刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语⾔的典型代表,其他的静态类型语⾔还有C#、JAVA等。
对于动态语⾔与静态语⾔的区分,套⽤⼀句流⾏的话就是:Static typing when possible, dynamic typing when needed。
强类型定义语⾔和弱类型定义语⾔
(1)强类型定义语⾔:强制数据类型定义的语⾔。也就是说,⼀旦⼀个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例⼦:如果你定义了⼀个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语⾔是类型安全的语⾔。
(2)弱类型定义语⾔:数据类型可以被忽略的语⾔。它与强类型定义语⾔相反, ⼀个变量可以赋不同数据类型的值。
强类型定义语⾔在速度上可能略逊⾊于弱类型定义语⾔,但是强类型定义语⾔带来的严谨性能够有效的避免许多错误。另外,“这门语⾔是不是动态语⾔”与“这门语⾔是否类型安全”之间是完全没有联系的!
例如:Python是动态语⾔,是强类型定义语⾔(类型安全的语⾔); VBScript是动态语⾔,是弱类型定义语⾔(类型不安全的语⾔); JAVA是静态语⾔,是强类型定义语⾔(类型安全的语⾔)。
静态类型定义语⾔
⼀种在编译时,数据类型是固定的语⾔。⼤多数静态类型定义语⾔强制这⼀点,它要求你在使⽤所有变量之前要声明它们的数据类型。Java和C是静态类型定义语⾔。
动态类型定义语⾔
⼀种在执⾏期间才去发现数据类型的语⾔,与静态类型定义相反。VBScript和Python是动态类型定义的,因为它们是在第⼀次给⼀个变量赋值的时候出它的类型的。
强类型定义语⾔
⼀种总是强制类型定义的语⾔。Java和Python是强制类型定义的。如果你有⼀个整数,如果不显⽰地进⾏转换,你不能将其视为⼀个字符串。
弱类型定义语⾔
⼀种类型可以被忽略的语⾔,与强类型定义相反。VBScript是弱类型定义的。在VBScript中,可以将字符串'12'和整数3进⾏连接得到字符串'123',然后可以把它看成整数123,⽽不需要显⽰转换。但其实它们的类型没有改变,VB只是在判断出⼀个表达式含有不同类型的变量之后,⾃动在这些变量前加了⼀个clong()或(int)()这样的转换函数⽽已.能做到这⼀点其实是归功于VB的编译器的智能化⽽已,这并⾮是VB语⾔本⾝的长处或短处.
结论:
静态是类型编译时判断;动态是类型运⾏时判断;强类型是类型独⽴,不轻易转化;弱类型是类型不严格区分,⼀般是只要⼤⼩放得下,就可以转化。这种是汇编级的观点。⾯向对象的观点并⾮这样的,对象并不是⼤⼩差不多就是类型兼容,⽽是关键的接⼝要相同才叫类型兼容。
动态语⾔并⾮是弱类型,这是不等价的。恰好的,⼀般动态语⾔都是强类型语⾔,因为都是遵照⾯向对象的观点来设计对象的。
动态语⾔的劣势很明显,就是缺少开发环境,运⾏效率差,当然语⾔设计上也不完美(静态语⾔何⽌千万,但c++也就⼀个)。
优势也很明显,就是编写容易,层次⾼,接近⾃然语义。动态类型语⾔效率低下的原因,不在于变量的类型是动态的,⽽在于对象的⽅法是动态联编的,在这⼀点上动态类型语
⾔和Java没什么不同。
静态类型语⾔的优势究竟是什么?
观点⼀:静态类型语⾔因为类型强制声明,所以IDE可以做到很好的代码感知能⼒,因为有IDE的撑腰,所以开发⼤型系统,复杂系统⽐较有保障。
对于像Java来说,IDEA/Eclipse确实在代码感知能⼒上⾯已经⾮常强了,这⽆疑能够增加对⼤型系统复杂系统的掌控能⼒。但是除了Java拥有这么强的IDE武器之外,似乎其他
语⾔从来没有这么强的IDE。C#的Visual Studio在GUI开发⽅⾯和Wizard⽅⾯很强,但是代码感知能⼒上和Eclipse差的不是⼀点半点。⾄于Visual C++根本就是⼀个编译器⽽
已,羞于提及Visual这个字眼。更不要说那么多C/C++开发⼈员都是操起vi吭哧吭哧写了⼏⼗万⾏代码呢。特别是像Linux Kernel这种⼏百万⾏代码,也就是⽤vi写出来的阿,够
复杂,够⼤型,够长⽣命周期的吧。
观点⼆:静态语⾔相对⽐较封闭的特点,使得第三⽅开发包对代码的侵害性可以降到很低。动态语⾔在这点上表现的就⽐较差,我想⼤家都有过从⽹上下载某个JS包,然后放到
项⽬代码⾥发⽣冲突的经历
也就是说静态类型语⾔可以保障package的命名空间分割,从⽽避免命名冲突,代码的良好隔离性。但是这个观点也缺乏说服⼒。
静态类型语⾔中C,VB都缺乏良好的命名空间分割,容易产⽣冲突,但是并没有影响他们做出来的系统就不够⼤,不够复杂。
⽽Visual C++开发的DLL版本冲突也是臭名昭著的,似乎C++的命名空间没有给它带来很⼤的帮助。
⽽动态类型语⾔中Ruby/Python/Perl都有⽐较好的命名空间,特别是Python和Perl,例如CPAN上⾯的第三⽅库成吨成吨的,也从来没有听说什么冲突的问题。
诚然像PHP,JavaScript这样缺乏命名空间的动态语⾔很容易出现问题,但是这似乎是因为他们缺乏OO机制导致的,⽽不是因为他们动态类型导致的吧?
说到⼤型系统,复杂业务逻辑系统,Google公司很多东西都是⽤python开发的,这也证明了动态类型语⾔并⾮不能做⼤型的复杂的系统。其实我个⼈认为:
动态类型语⾔,特别是⾼级动态类型语⾔,反⽽能够让⼈们不需要分⼼去考虑程序编程问题,⽽集中精⼒思考业务逻辑实现,即思考过程即实现过程,⽤DSL描述问题的过程就
是编程的过程,这⽅⾯像Unix Shell,ruby,SQL,甚⾄PHP都是相应领域当之⽆愧的DSL语⾔。⽽显然静态类型语⾔基本都不满⾜这个要求。
那静态类型语⾔的优势究竟是什么呢?我认为就是执⾏效率⾮常⾼。所以但凡需要关注执⾏性能的地⽅就得⽤静态类型语⾔。其他⽅⾯似乎没有什么特别的优势。
给你来个例⼦把
弱类型语⾔vbs:
a=1
目前流行的编程语言b=a+"1"+"a" //结果是11a,这⾥ a 成了字符串
c=a+1 //结果是2 ,这⾥a则是数字型
强类型语⾔:c#
int a=2
string b=a.ToString()+"1"+"a"
int c=a+1
看到了吗?区分⼤⼩写,需要实现申明类型外,⼀个重要的区别是,弱类型的语⾔的东西没有明显的类型,他能随着环境的不同,⾃动变换类型
⽽强类型则没这样的规定,不同类型间的操作有严格定义,只有相同类型的变量才能操作,虽然系统也有⼀定的默认转换,当绝没有弱类型那么随便
ps:弱类型代码简单,但因为变量没有确定的类型,所以容易出错!强类型代码复杂(⽐如:转换⽇期显⽰格式 (Datetime("2007-1-1 08:08:08")).ToString("yyyy-MM-dd"),呵呵你可以看到这种写法相当⿇烦),但因为有严格定义所以不容易出错
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论