
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
随着互联网编程技术的不断发展,现在大多数的软件开发都是通过java编程语言来实现的,今天我们就一起来了解一下C语言编程开发技术都有哪些优势和劣势。
C语言的一些好的体验
一次通过阅读POV-Ray源代码学会如何在C语言中实现面向对象编程。
通过阅读GTK+源代码了解C语言代码的清晰、干净和可维护性。
通过阅读SIOD和Guile的源代码,知道如何使用C语言实现Scheme解析器。
使用C语言写出GNOME Eye的初始版本,并对MicroTile渲染进行调优。
C语言的一些不好的体验
在Evolution团队时,很多东西老是崩溃。那个时候还没有Valgrind,为了得到Purify这个软件,需要购买一台Solaris机器。
调试gnome-vfs线程死锁问题。
调试Mesa,却无果。
接手Nautilus-share的初始版本,却发现代码里面居然没有使用free()。
想要重构代码,却不知道该如何管理好内存。
想要打包代码,却发现到处是全局变量,而且没有静态函数。
但不管怎样,还是来说说那些Rust里有但C语言里没有的东西吧。
自动资源管理
Rust从C++那里借鉴了一些想法,如RAII(Resource Acquisition Is Initialization,资源获取即初始化)和智能指针,并加入了值的单一所有权原则,还提供了自动化的决策性资源管理机制。
自动化:不需要手动调用free()。内存使用完后会自动释放,文件使用完后会自动关闭,互斥锁在作用域之外会自动释放。如果要封装外部资源,基本上只要实现Drop这个trait就可以了。封装过的资源就像是编程语言的一部分,因为你不需要去管理它的生命周期。
决策性:资源被创建(内存分配、初始化、打开文件等),然后在作用域之外被销毁。根本不存在垃圾收集这回事:代码执行完就都结束了。程序数据的生命周期看起来就像是函数调用树。
如果在写代码时老是忘记调用这些方法(free/close/destroy),或者发现以前写的代码已经忘记调用,甚至错误地调用,那么以后我再也不想使用这些方法了。
泛型
Vec真的就是元素T的vector,而不只是对象指针的数组。在经过编译之后,它只能用来存放类型T的对象。
在C语言里需要些很多代码才能实现类似的功能,所以我不想再这么干了。
trait不只是interface
Rust并不是一门类似Java那样的面向对象编程语言,它有trait,看起来就像是Java里的interface——可以用来实现动态绑定。如果一个对象实现了Drawable,那么就可以肯定该对象带有draw()方法。
不过不管怎样,trait的威力可不止这些。
依赖管理
以前实现依赖管理需要:
手动调用或通过自动化工具宏来调用pkg-config。
指定头文件和库文件路径。
基本上需要人为确保安装了正确版本的库文件。
而在Rust里,只需要编写一个Cargo.toml文件,然后在文件里指明依赖库的版本。这些依赖库会被自动下载下来,或者从某个指定的地方获取。
测试
C语言的单元测试非常困难,原因如下:
内部函数通常都是静态的。也就是说,它们无法被外部文件调用。测试程序需要使用#include指令把源文件包含进来,或者使用#ifdefs在测试过程中移除这些静态函数。
需要编写Makefile文件将测试程序链接到其中的部分依赖库或部分代码。
需要使用测试框架,并把测试用例注册到框架上,还要学会如何使用这些框架。
卫生宏(Hygienic Macro)
Rust的卫生宏避免了C语言宏可能存在的问题,比如宏中的一些东西会掩盖掉代码里的标识符。Rust并不要求宏中所有的符号都必须使用括号,比如max(5 + 3, 4)。
没有自动转型
在C语言里,很多bug都是因为在无意中将int转成short或char而导致,而在Rust里就不会出现这种情况,因为它要求显示转型。
不会出现整型溢出
这个就不用再多作解释了。
在安全模式下,Rust里几乎不存在未定义的行为
在Rust的“安全”模式下编写的代码(unsafe{}代码块之外的代码)如果出现了未定义行为,可以直接把它当成是一个bug来处理。比如,将一个负整数右移,这样做是完全可以的。
模式匹配
在对一个枚举类型进行switch操作时,如果没有处理所有的值,gcc编译器就会给出警告。
Rust提供了模式匹配,可以在match表达式里处理枚举类型,并从单个函数返回多个值。
标准的错误处理
在Rust里,不再只是简单地返回一个布尔值表示出错与否,也不再简单粗暴地忽略错误,也不再通过非本地跳转来处理异常。
#[derive(Debug)]
在创建新类型时(比如创建一个包含大量字段的struct),可以使用#[derive(Debug)],Rust会自动打印该类型的内容用于调试,不需要再手动编写函数去获取类型的信息。
闭包
不再需要使用函数指针了。
结论
在多线程环境里,Rust的并发控制机制可以防止出现数据竟态条件。我想,对于那些经常写多线程并发代码的人来说,这会是个好消息。
C语言是一门古老的语言,用它来编写单处理器的Unix内核或许是个不错的选择,但对于现今的软件来说,它算不上好语言。
Rust有一定的学习曲线,但我觉得完全值得一学。它之所以不好学,是因为它要求开发者对自己所写的代码必须有充分的了解。我想,Rust是一门这样的语言:它可以让你变成更好的开发者,而且它会成为你解决问题的利器。
作者:Federico
译者:Martin
来源:infoq
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。