模块

模块 属于 Crystal

1 个练习

关于 模块

Crystal 中的模块有两个用途:

第一个用途是创建命名空间,以避免名称冲突。 不过,它也会把代码组织起来,让人更容易看懂代码的用途。

第二个用途是定义混入,把代码共享给各个类型。

模块和类很相似,但主要区别在于:模块不能被实例化,因此也没有实例变量。

要声明一个模块,使用module关键字,后面跟上模块的名字。

module Foo
end

命名空间

命名空间是一种组织代码的方式。 这样可以避免名称冲突,也更容易看清代码的用途。 如果想访问放在某个命名空间里的常量或类,就要使用::运算符。

module Foo
  class Bar
  end
end

Foo::Bar.new

把模块用作混入

例如,当多个类需要相同的“基础”功能,或者需要在互不相关的类之间共享代码时,这就会很有用。 或者,当你想在不相关的类之间共享代码时,也可以这么做。

把模块用作混入有两种方式:第一种是使用include关键字,第二种是使用extend关键字。

两种方式都会让模块中的常量对包含或扩展该模块的类型可用。

包含

包含会让模块中的所有方法都变成包含该模块的类型的实例方法。 include关键字应写在类型的顶部,后面跟上模块的名字。

module Foo
  def foo
    "foo"
  end
end

class Bar
  include Foo
end

Bar.new.foo # => "foo"

扩展

扩展的用法和包含类似,但它不会把方法变成实例方法,而是把它们变成类方法。 extend关键字应写在类型的顶部,后面跟上模块的名字。

module Foo
  def foo
    "foo"
  end
end

class Bar
  extend Foo
end

Bar.foo # => "foo"

extend self

Crystal 中一种常见的模式,是在模块里使用 extend self 模式。 这样,模块中的所有方法都会变成模块自身的类方法。 这意味着你不需要用def self.method_name语法把每个方法都挂到模块上。

module Foo
  extend self

  def foo
    "foo"
  end
end

Foo.foo # => "foo"
通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 模块

练习已锁定

再解锁 2 个练习即可练习 模块