很难用一个列表来描述 Ruby 与 C 或 C++ 代码的不同之处,因为差异相当大。其中一个原因是 Ruby 的运行时帮你做了很多工作。与 C 的“不隐藏内部机制”原则不同——Ruby 的关注点在于将繁重的工作交由运行时,使用者站在运行时的肩上,活的更轻松。除非或直到做代码优化,使用 Ruby 不用费心“让编译器高兴” 。
换句话说,Ruby 代码执行速度远远慢于“等价”的 C 或 C++ 代码是确定无疑的。相同的时间内,你头脑里关注的是如何快速的将一个 Ruby 程序运行起来,而且只需要很少的代码就可以做到。和把你搅成一锅粥的 C++ 相比,Ruby 要简单的多。
Ruby 是动态类型语言,而不是静态类型。它在运行的时候运行时做尽可能多的事。例如,你不用关心 Ruby 程序“链接”(也就是载入和使用)到哪里或之前调用什么方法。
可喜的是,事实证明 Ruby 和 C 之间的共生关系很和谐。Ruby 支持所谓“扩展模块”。这些模块由 C 语言编写,可以被 Ruby 程序调用(从外部来说,与其他 Ruby 模块表现和行为毫无二致)。通过这种方式,可以将性能关键部分从 Ruby 软件中切分出来,再由 C 语言打造。
当然,Ruby 本身是由 C 语言写的。
与 C 相似点
Ruby 与 C 一样的地方……
- 如果喜欢,你可以面向过程编程(但是实际上仍然是面向对象)。
- 大多数的操作符是一样的(包括赋值操作和位操作)。但 Ruby 没有
++
或--
。 - 有
__FILE__
和__LINE__
。 - 虽然没有
const
关键字,但常量还是有的。常量由命名约定约束——以大写字母开头的是常量。 - 字符串使用双引号。
- 字符串是可变类型。
- 与 man pages 类似,在终端窗口内使用
ri
命令可以浏览大部分文档。 - 可以使用同样的命令行调试器。
与 C++ 相似点
Ruby 与 C++ 一样的地方……
- 几乎一样的操作符(甚至
::
)。<<
常用于向列表内追加元素。值得注意的是:Ruby 使用.
,而不使用->
。 public
、private
和protected
功能类似。- 继承语法仍然只用一个字符,由
<
变成:
。 - 你可以将代码放进“模块”内,与 C++ 中使用
namespace
类似。 - 为避免殃及池鱼,修改了异常(Exceptions)关键字, 但它们的工作类似。
与 C 相异点
Ruby 与 C 不同的地方……
- 对象是强类型(变量名本身完全没有类型)。
- 没有宏或预处理。没有类型转换。没有指针(也没有指针运算)。没有typedef,sizeof, enums。
- 没有头文件。只需要在源码文件中定义你的函数(通常称作“方法”)和类即可。
- 没有
#define
。使用常量代替。 - 就 Ruby 1.8 而言,代码在运行时解释,而不是编译成任何机器码或二进制码。
- 所有的变量存在于堆(heap)内。因此,不需要手动释放,垃圾回收器会帮你处理。
- 参数通过引用传递给方法(如:函数),不是通过值传递。
- 使用
require 'foo'
,而不是#include <foo>
或#include "foo"
。 - 不能在程序中插入组合语言。
- 行末尾没有分号。
if
和while
条件表达式不需要括号。- 方法调用的括号(如:函数)通常可选。
- 通常不使用括号,使用
end
关键字结束多行结构。 do
关键字用于所谓的“代码块”。没有像 C 语言那样的“do statement”。- “代码块”意义不同。意思是当方法执行时方法体内调用的一系列代码。
- 没有变量声明。需要时再赋予一个新的名字即可。
- 判断真值时,只有
false
和nil
当做假值。其余一切皆为真(包括0
、0.0
、""
和[]
)。 - 没有
char
类型,有的是只包含一个字符的字符串。 - 字符串不是以空字节结束。
- 数组字面量使用括号而不是花括号。
- 数组中加入更多元素时,数组会自动变大。
- 数组相加,返回的是一个新的更大的数组(当然,分配在堆(heap)上)而不是进行指针运算。
- 基本上,一切皆表达式(也就是说,像
while
声明也会有右值)。
与 C++ 相异点
Ruby 与 C++ 不同的地方……
- 没有明确引用。也就是在 Ruby 中,一切变量只是对象的一个自动非关联名称。
- 对象是强类型也是动态类型。 运行时在运行的时候才知道方法调用是否可用。
- “构造器”是
initialize
而不是类名。 - 一切方法都是虚的。
- “类”(静态)变量名总是以
@@
开头(像@@total_widgets
这样)。 - 你不是直接访问成员变量,所有公开的成员变量( Ruby 中称为属性)都通过方法访问。
- 使用
self
代替this
。 - 有一些以
?
或!
结尾的方法。这些符号实际是方法名的一部分。 - 没有多重继承。然而 Ruby 有 “混入(mixins)”(比如,你可以“继承”某个模块的所有方法)。
- 有一些强制命名约定(例如:类名以大写字母开头,变量以小写字母开头)。
- 方法调用的括号是可选的。
- 随时重新打开类并增加方法。
- 不需要 C++ 模板(因为类型在运行时确定,所以可以给变量分配任意类型的对象),也没有类型转换。
- 迭代有一点点区别。Ruby 中,不使用单独的迭代对象(像
vector<T>::const_iterator iter
),当你的对象混入Enumerator
模块,你就可以像my_obj.each
这样调用方法。 - 只有两种容器类型: 数组
Array
和哈希Hash
。 - 无类型转换。 你会发现在 Ruby 中,这没有必要。
- 内置多线程,就 Ruby 1.8 而言是“绿色线程”(只在解释器中实现)而非原生线程。
- Ruby 标准库包含了单元测试库。