Ruby 中的 nil 值和 nilClass 类

yufei       6 年, 3 月 前       3896

Ruby 是一个完全的面向对象 ( OOP ) 的编程语言,哪怕是一个普通的 nil 值,背后也存在着一个类 NilClass 。本章节,我们就来探究下 Ruby 中的 nil 值和它背后的实现,我们将涉及到以下几个问题

  • nil
  • NilClass
  • nil? 方法实现

nil 值

我们首先来探寻下 nil 值。

Ruby 中的 nil 值的含义是用于表示 「 缺失对象 」的概念

nil 值也被垃圾收集器使用 - 它实现了标记和扫描算法 - 来决定是否应该销毁一个对象

与其他语言不同,Ruby 中的 nil 值并不用于表示空字符串 ''false 或 0 值。

由于 Ruby 中的所有内容都是对象,因此 nil 值它属于一个类,一个不可实例化的 NilClass

NilClass 类

NilClassRuby 的内置 ( built-in ) 类。此类不可实例化。

irb> NilClass.new
NoMethodError (undefined method `new' for NilClass:Class)

当一个消息发送到 nil 时,会有一个名为 rb_cNilClass 的硬编码 C 语言类( 对应于 Ruby 中的NilClass )被用作消息的接收者。

然后将在新接收器的实例方法中找到和发送消息

因此,nil 更像是关键字而不是实例。因为它只是表达 「 缺失对象 」概念的一种方式

另一方面,NilClass 封装了所有逻辑,并在消息的接收者为 nil 时使用

nil? 方法

调用 nil? 方法可用于确定接收器是否为一个对象

irb> "I'm an object".nil?
 => false
irb> a = nil
 => nil
irb> a.nil?
 => true

很简单,不是吗?

你是不是跟我一样好奇,这个 nil? 方法在内部是如何实现的。那么,我们就一起来看看 Ruby 源代码吧。

Ruby 是用 C 语言 编写的。但是,不要惊慌,如果你不熟悉这种编程语言,也没关系,因为我们看的代码非常简单

// in ruby/object.c
void InitVM_Object(void) {
  ...
  rb_define_method(rb_mKernel, "nil?", rb_false, 0);
  ...
  rb_define_method(rb_cNilClass, "nil?", rb_true, 0);
  ...
}

Ruby 虚拟机 ( VM ) 启动期间会调用 InitVM_Object 函数。此函数负责设置与 Object 类相关的所有环境和类

rb_define_method(klass,message,function,argc) 用于向模块/类添加消息并将此消息链接到 C 语言级别的函数。

因此,上面的代码中,rb_define_method(rb_mKernel,“nil?”,rb_false,0); 就是把 nil? 消息添加到内核模块并将此消息链接到 rb_false 函数

rb_define_method 方法的最后一个参数是传递给给方法的参数数量 - 这里没有预期的参数,所以是 0

由于 Kernel 模块包含在 Object 类中,而 Object 类是 Ruby 中所有类的默认父类,因此,几乎所有类都可以处理 nil? 方法

rb_false 方法

接下来,我们来看看 rb_false 方法是如何实现的。

static VALUE
rb_false(VALUE obj)
{
    return Qfalse;
}

rb_false 函数返回一个 Qfalse - 这是 Ruby C 语言级别的 false 值。

这就意味着,默认情况下,所有的对象都不是 nil

最后,我们通过 rb_true 函数来看看 NilClass#nil 的实现

static VALUE
rb_true(VALUE obj)
{
    return Qtrue;
}

rb_true 函数返回一个 Qtrue - 这是 Ruby C 语言级别的 true 值。

这意味着 NilClass#nil? 方法重写了 Kernel#nil? 方法 (返回 false ) 使其返回 true

这是一个聪明的实现,通过使用继承来特殊化 NilClass 类来遵守 OOP 原则

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.