很难用一个项目符号列表来描述你的代码在 Ruby 中与 C 或 C++ 有何不同,因为它们之间的差异非常大。其中一个原因是 Ruby 运行时为你做了很多事情。Ruby 似乎与 C 的“没有隐藏机制”原则相去甚远——Ruby 的全部意义在于通过让运行时承担更多的工作,使人类的工作更容易。除非你对代码进行性能优化分析,否则在使用 Ruby 时,你不需要关心“让你的编译器高兴”。
也就是说,一方面,你可以预期你的 Ruby 代码的执行速度比“等效”的 C 或 C++ 代码慢得多。同时,你会惊讶于你能多么迅速地启动并运行一个 Ruby 程序,以及编写它需要多么少的代码行。Ruby 比 C++ 简单得多——它会把你宠坏的。
Ruby 是动态类型的,而不是静态类型的——运行时尽可能多地在运行时进行。例如,你不需要提前知道你的 Ruby 程序将“链接到”(即加载和使用)哪些模块,或者它将调用哪些方法。
令人高兴的是,事实证明 Ruby 和 C 有着健康的共生关系。Ruby 支持所谓的“扩展模块”。这些模块你可以从你的 Ruby 程序中使用(并且从外部看起来,它们和任何其他 Ruby 模块一样),但是它们是用 C 编写的。这样,你可以将 Ruby 软件中对性能至关重要的部分进行隔离,并将它们提炼为纯 C 代码。
当然,Ruby 本身就是用 C 编写的。
与 C 的相似之处
与 C 类似,在 Ruby 中,…
- 如果你愿意,你可以进行过程式编程(但它在幕后仍然是面向对象的)。
- 大多数运算符是相同的(包括复合赋值和位运算符)。尽管如此,Ruby 没有
++
或--
。 - 你有
__FILE__
和__LINE__
。 - 你也可以有常量,尽管没有特殊的
const
关键字。常量的特性是通过命名约定来强制执行的——以大写字母开头的名称用于常量。 - 字符串用双引号括起来。
- 字符串是可变的。
- 就像 man 手册一样,你可以在终端窗口中阅读大多数文档——尽管使用的是
ri
命令。 - 你有相同的命令行调试器可用。
与 C++ 的相似之处
与 C++ 类似,在 Ruby 中,…
- 你拥有大多数相同的运算符(甚至包括
::
)。<<
通常用于将元素追加到列表中。但请注意:在 Ruby 中你永远不会使用->
——它总是只是.
。 public
、private
和protected
执行类似的任务。- 继承语法仍然只有一个字符,但它是
<
而不是:
。 - 你可以将你的代码放入“模块”中,类似于 C++ 中
namespace
的使用方式。 - 异常的工作方式类似,尽管关键字名称已被更改以保护无辜者。
与 C 的不同之处
与 C 不同,在 Ruby 中,…
- 你不需要编译你的代码。你只需直接运行它。
- 对象是强类型的(并且变量名本身没有任何类型)。
- 没有宏或预处理器。没有类型转换。没有指针(也没有指针算术)。没有 typedefs、sizeof 或 enums。
- 没有头文件。你只需在主源代码文件中定义你的函数(通常称为“方法”)和类。
- 没有
#define
。只需使用常量代替。 - 所有变量都存在于堆上。此外,你不需要自己释放它们——垃圾收集器会处理这个问题。
- 方法的参数(即函数)是按值传递的,其中这些值始终是对象引用。
- 它是
require 'foo'
而不是#include <foo>
或#include "foo"
。 - 你不能下降到汇编语言。
- 行尾没有分号。
- 对于
if
和while
条件表达式,你不需要括号。 - 方法(即函数)调用的括号通常是可选的。
- 你通常不使用花括号——只需用
end
关键字结束多行结构(如while
循环)。 do
关键字用于所谓的“代码块”。没有像 C 中的“do 语句”。- 术语“代码块”意味着不同的东西。它用于与方法调用关联的代码块,以便方法体在执行时可以调用该代码块。
- 没有变量声明。你只需在需要时动态地分配新名称。
- 在测试真值时,只有
false
和nil
评估为假值。其他一切都是真值(包括0
、0.0
和"0"
)。 - 没有
char
——它们只是一个字母的字符串。 - 字符串不以空字节结尾。
- 数组字面量用方括号而不是花括号括起来。
- 当你将更多元素放入数组时,数组会自动变大。
- 如果添加两个数组,你会得到一个新的更大的数组(当然,在堆上分配),而不是进行指针算术。
- 通常情况下,一切都是表达式(也就是说,像
while
语句这样的东西实际上会评估为一个右值)。
与 C++ 的不同之处
与 C++ 不同,在 Ruby 中,…
- 没有显式引用。也就是说,在 Ruby 中,每个变量都只是某些对象的自动解引用名称。
- 对象是强类型但动态类型的。运行时在运行时发现该方法调用是否真的有效。
- “构造函数”称为
initialize
,而不是类名。 - 所有方法始终是虚拟的。
- “类”(静态)变量名始终以
@@
开头(如@@total_widgets
)。 - 你不会直接访问成员变量——对公共成员变量(在 Ruby 中称为属性)的所有访问都通过方法进行。
- 它是
self
而不是this
。 - 一些方法以 ’?’ 或 ’!’ 结尾。它实际上是方法名称的一部分。
- 没有严格意义上的多重继承。尽管 Ruby 有“混入”(即你可以“继承”模块的所有实例方法)。
- 有一些强制执行的大小写约定(例如,类名以大写字母开头,变量以小写字母开头)。
- 方法调用的括号通常是可选的。
- 你可以随时重新打开一个类并添加更多方法。
- 不需要 C++ 模板(因为你可以将任何类型的对象分配给给定的变量,并且类型在运行时会被解析)。也没有类型转换。
- 迭代的完成方式略有不同。在 Ruby 中,你不使用单独的迭代器对象(如
vector<T>::const_iterator iter
)。相反,你使用容器对象的迭代器方法(如each
),该方法接受一个代码块,并将连续的元素传递给该代码块。 - 只有两种容器类型:
Array
和Hash
。 - 没有类型转换。不过,使用 Ruby 你可能会发现它们不是必需的。
- 多线程是内置的,但从 Ruby 1.8 开始,它们是“绿色线程”(仅在解释器中实现),而不是原生线程。
- 单元测试库是 Ruby 的标准配置。