分享

从C 和C++到Ruby

 思考的轨迹 2012-02-21

由于Ruby 跟C/C++ 的差异实在太大,很难将两者间的差异一项一项列出。其中的一个重要理由是:Ruby 和C 语言的「不隐藏内部机制(No hidden mechanism)」原则完全处在两个极端上。Ruby 选择让人们的工作更轻松,但让执行期环境(runtime)负担加重。除非你要开始对你的Ruby 程式码做最佳化,你不需要关心编译器的脸色如何。

也就是说,你可以预期Ruby 程式将会比等价的C/C++ 程式慢的多。然而,你也会惊讶于只需要写这么少的程式码,就可以迅速地完成你的Ruby 程式。Ruby 能完全满足你的需求,又比C++简单的多。

Ruby 是动态型别(Dynamically typed),而不是静态型别(Statically typed)的程式语言。Ruby的执行期环境(runtime)会尽可能的处理所有工作。举例来说,你不需要事先知道你的Ruby 程式将会被连结(link)到哪一个模组,或是哪一个方法(method)将会被呼叫。

幸运的是,Ruby 与C 有着良好的共生关系。Ruby 支援所谓的「扩充模组」。这些由C 语言写成的模组能够在Ruby 程式中使用(而且看起来与一般Ruby 模组无异)。因此,你可以将你的Ruby 程式中影响效能最大的部份划分出去,用纯粹的C 语言来完成这些部分。

最后,Ruby 本身理所当然的是用C 语言写成。

与C语言的相似之处

与C语言相同,在Ruby中...
  • 你可以用程序式的方式写程式(但是底层依然是物件导向的环境。)
  • 大多数的运算子都是相同的。(包含复合运算子跟位元运算子。)然而Ruby并没有++或是--运算子。
  • 你可以使用__FILE____LINE__
  • 你可以定义常数。虽然并没有特殊的const关键字,Ruby利用命名的惯例来强迫变数为常数:第一个字母为大写的变数便为常数。
  • 字串由双引号包住。
  • 字串是可变的。
  • 就像man page一样,你可以利用ri指令在终端机视窗中阅读大多数的文件。
  • 你也有一样的指令列debugger可以使用。

与C++的相同之处

与C++相同,在Ruby中...
  • 大多数的运算子都是一样的(包含::),<<常常用来将元素串接在list之后。要注意的是:Ruby中你不需要使用->,永远只需要.
  • publicprivate,与protected的功能在两者是类似的。
  • 物件的继承一样只需要一个字元,只是从:变成<
  • 可以将你的程式码放进模组(module)之中,类似C++中的namespace的作法。
  • 例外(Exceptions)的运作方式类似。虽然为了保护无辜的人们,我们把关键字改了。

与C语言的不同之处

与C语言不同的是,在Ruby中...
  • 物件是强型别。(变数名称则没有任何的型别定义。)
  • 没有巨集(macro)或是前处理器(preprocessor)、没有转型??、没有指标。
  • 没有标头档(header files)、没有typedef、没有sizeof、也没有enums。
  • 没有#define用常数来代替他们便可。
  • 在Ruby 1.8中,程式码在执行期才被解译,而不是被编译成任何一种机械语言或是byte-code。
  • 所有的变数都存放在堆叠(heap)中。因此,你不需要自行释放他们,垃圾回收机制(Garbage collector)会处理他们。
  • 方法的参数是传参考,而非传值。
  • require 'foo'而不是#include <foo>或是#include "foo"
  • 你不能在程式码中插入组合语言。
  • 每行的结尾不需要分号。
  • ifwhile这类条件运算式中,你可以省略括号。
  • 呼叫方法的括号通常是选择性的。
  • 你不会常常使用大括号。一般只需要使用end关键字来结束一个多行的区块(像是while回圈。)
  • do关键字被称作「block」,Ruby中没有C语言的「do statement。」
  • 「block」这个词在Ruby 中有着不同的意义。它是指一段可以结合到一个方法呼叫的程式码,使得该方法的本体在执行时可以呼叫该段程式码。
  • 你不需要事先宣告变数,当你需要一个变数时直接使用一个新名字就可以了。
  • 当测试真值的时候,除了falsenil之外的东西都视为真(包含00.0,以及"0"。)
  • Ruby没有字元(char)型别,只有长度为一的字串。
  • 字串并不需要一个空位元组作为结束。
  • 阵列宣告使用中括号而非大括号。
  • 当你加入更多元素到阵列中时,阵列会自动变大。
  • 如果你将两个阵列相加,你会得到一个更大的新的阵列,而不是指标运算的结果。
  • 大多数的情况下,一切都是一个运算式。(也就是说,while之类的东西实际上会被当做一个rvalue。)

与C++的不同

与C++不同的是,在Ruby中...
  • 你不能明确的定义参照(reference),Ruby中每个变数都会被自动解参照回原本的物件。
  • 物件型别是强型别也是动态型别。Ruby执行期环境将会在执行期的方法呼叫成功时,自行辨识型别。
  • 物件的建构子用initialize命名,而不是类别名称。
  • 所有的方法都是虚拟(virtual)的。
  • 类别变数(静态变数)的变数名称永远用@@开头。
  • 你不能直接存取成员变数,所有对公开的成员变数(在Ruby中称作属性, attribute)的存取都会透过方法呼叫。
  • self取代this
  • 有些方法会以'?' 或是'!'结尾,这些符号都真的存在于方法名称中。
  • 本质上,Ruby没有多重继承。然而,Ruby可以使用”mixin”。(也就是说,你可以「继承」某个模组的所有方法)
  • 呼叫方法时的括号通常都可以省略。
  • 你可以在任何时候重新打开一个类别以加入新的方法。
  • 你不需要C++ 的template 机制。(因为你可以将某个变数设值为任何一种物件,型别将在执行期自动辨识。)你也不需要转型。
  • 迭代(Iteration)的运作方式有些许不同,Ruby中你会让你的物件mixin Enumerator模组并且直接呼叫my_obj.each方法,而不是使用一个独立的迭代器(Iterator)。
  • Ruby只有两种容器类别:ArrayHash
  • Ruby没有型别转换,你也会发现在Ruby中你不需要它们。
  • Ruby内建了多执行绪。但是在Ruby 1.8之中只有”green threads”(只在直译器中有效的执行绪),而不是原生的执行绪。
  • Ruby的标准函式库中就包含了单元测试(Unit test)函式库。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多