Ruby mixin 编程之 - Comparable ( 可比较的 ) mixin

yufei       6 年, 3 月 前       1061

「 mixin 」 这个概念,在 Ruby 中有,在 Python 中也有,有时候会看到有些文章翻译成 「 混入 」,但更多的是直接使用 mixin 。因此,本文就直接使用 mixin 而不翻译为 「 混入 」 了

mixin 、extend 和 composite

在继续讲解 mixin 之前,我们先来区分下 「 mixin 」 、继承/扩展 ( extend ) 和组合 ( composite ),这三者代表啥意思呢?

它们代表的是一个类和另一个类之间产生关系的几种机制:

  1. 一个类是另一个类的祖先类,这种用的是 扩展 extend
  2. 两个之间并没有任何关系,只是在一个类的方法中会实例化另一个类,这是 组合
  3. 一个类和另一个类之间没有任何关系,只是在实例化的时候结合了另一个类,这种就是 mixin

这个说明有点不恰当,不过大概意思已经到了。

要充分理解三者的区别,就要从它们之实例化之前有没有关系,实例化时的相互关系方面着手

Comparable mixin

回到我们的正题,我们今天要讲解的是 Comparable mixin 。Compare mixin 是 Ruby 核心的重要组成部分。

它通常用于需要比较的类中,包含了一堆用于对象比较目的的方法

例如,NumericString 类包含此 mixin

irb> Numeric.ancestors
 => [Numeric, Comparable, Object, Kernel, BasicObject]
irb> String.ancestors
 => [String, Comparable, Object, Kernel, BasicObject]

如果你想了解更多 Module#ancestors 方面的知识,可以访问我们的另一篇文章 Ruby 中的对象模型 ( object model ) ( 上 )

包含 Comparable 的类的实现

假设我们要根据 rank 属性来比较一些 profiles ( 用户资料 )

class Profile
  include Comparable
  attr :rank
  def initialize(rank)
    @rank = rank
  end
  def <=>(other_profile)
    rank <=> other_profile.rank
  end
end
irb> profile21 = Profile.new(21)
 => #<Profile:0x0404 @rank=21>
irb> profile42 = Profile.new(42)
 => #<Profile:0x0404 @rank=42>
irb> profile84 = Profile.new(84)
 => #<Profile:0x0404 @rank=84>
irb> profile84 > profile42
 => true
irb> profile84 < profile42
 => false
irb> profile84 == profile84
 => true
irb> profile21 <= profile42
 => true
irb> profile84 >= profile42
 => true

包含 Comparable mixin 的类必须响应 <=> 方法( 也称为太空船运算符 )。

太空船运算符方法是非常重要的,因为它是 Comparable mixin 中其它方法的基础方法 ,例如 ==<=>=>< 等等

由于 rank 属性是一个整型 ( Integer ),也就是 Numeric 类的直接子元素,因此可以使用 Numeric 实现的 <=> 方法安全的比较每个 rank 属性

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

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

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