很难用一个项目符号列表来描述你的 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
关键字。常量性是通过命名约定来强制执行的——以大写字母开头的名称用于常量。 - 字符串用双引号括起来。
- 字符串是可变的。
- 就像手册页一样,您可以在终端窗口中阅读大多数文档,尽管使用
ri
命令。 - 您拥有相同类型的命令行调试器。
与 C++ 的相似之处
与 C++ 一样,在 Ruby 中,…
- 您拥有大部分相同的运算符(甚至
::
)。<<
通常用于将元素追加到列表中。不过需要注意的是:在 Ruby 中,您永远不会使用->
,它始终只是.
。 public
、private
和protected
执行类似的任务。- 继承语法仍然只有一个字符,但它是
<
而不是:
。 - 您可以将代码放入“模块”中,类似于 C++ 中使用
namespace
的方式。 - 异常以类似的方式工作,尽管关键字名称已更改以保护无辜者。
与 C 的区别
与 C 不同,在 Ruby 中,…
- 您无需编译代码。您只需直接运行它。
- 对象是强类型化的(并且变量名本身没有任何类型)。
- 没有宏或预处理器。没有强制转换。没有指针(也没有指针运算)。没有类型定义、sizeof 或枚举。
- 没有头文件。您只需在主源代码文件中定义函数(通常称为“方法”)和类。
- 没有
#define
。只需使用常量代替。 - 所有变量都驻留在堆中。此外,您无需自己释放它们,垃圾收集器会处理这些问题。
- 方法(即函数)的参数按值传递,其中值始终是对象引用。
- 它是
require 'foo'
而不是#include <foo>
或#include "foo"
。 - 您不能降级到汇编。
- 没有以分号结尾的行。
- 对于
if
和while
条件表达式,您无需使用括号。 - 方法(即函数)调用的括号通常是可选的。
- 通常您不需要使用花括号,只需使用
end
关键字结束多行结构(如while
循环)。 do
关键字用于所谓的“块”。与 C 语言不同,没有“do 语句”。- “块”一词的含义不同。它用于与方法调用关联的代码块,以便方法体在执行时可以调用该块。
- 没有变量声明。您只需在需要时动态地为新名称赋值。
- 在测试真值时,只有
false
和nil
评估为假值。其他所有内容都为真(包括0
、0.0
和"0"
)。 - 没有
char
- 它们只是 1 个字母的字符串。 - 字符串不以空字节结尾。
- 数组字面量用方括号而不是花括号括起来。
- 当您向数组中添加更多元素时,数组会自动变大。
- 如果您添加两个数组,您将获得一个新的更大的数组(当然,分配在堆上),而不是执行指针运算。
- 通常情况下,所有内容都是表达式(也就是说,像
while
语句这样的东西实际上会评估为一个右值)。
与 C++ 的区别
与 C++ 不同,在 Ruby 中,…
- 没有显式引用。也就是说,在 Ruby 中,每个变量都只是某个对象的自动解引用名称。
- 对象是强类型但动态类型的。运行时在运行时发现该方法调用是否真正有效。
- “构造函数”称为
initialize
,而不是类名。 - 所有方法始终是虚拟的。
- “类”(静态)变量名始终以
@@
开头(如@@total_widgets
)。 - 您不能直接访问成员变量 - 对公共成员变量(在 Ruby 中称为属性)的所有访问都是通过方法进行的。
- 它是
self
而不是this
。 - 一些方法以 '?' 或 '!' 结尾。它实际上是方法名的一部分。
- 没有真正的多重继承。尽管 Ruby 有“mixin”(即您可以“继承”模块的所有实例方法)。
- 有一些强制的案例约定(例如,类名以大写字母开头,变量名以小写字母开头)。
- 方法调用的括号通常是可选的。
- 您可以随时重新打开一个类并添加更多方法。
- 不需要 C++ 模板(因为您可以将任何类型的对象分配给给定变量,并且类型在运行时确定)。也不需要强制转换。
- 迭代的方式略有不同。在 Ruby 中,您不使用单独的迭代器对象(例如
vector<T>::const_iterator iter
)。相反,您使用容器对象的迭代器方法(例如each
),该方法接受一个代码块,并将连续的元素传递给该代码块。 - 只有两种容器类型:
Array
和Hash
。 - 没有类型转换。不过,使用 Ruby,您可能会发现它们没有必要。
- 多线程是内置的,但从 Ruby 1.8 开始,它们是“绿色线程”(仅在解释器中实现),而不是原生线程。
- Ruby 自带一个单元测试库。