Crystal 的模組有兩個用途:
第一個用途是建立命名空間,避免名稱衝突。 不過,它同時也會將程式碼分組,讓人更容易理解程式碼的用途。
第二個用途是定義混入,把程式碼分享給型別。
模組和類別很相似,但最主要的差別在於模組無法被實體化,因此沒有實體變數。
要宣告一個模組,使用 module 關鍵字,後面接模組名稱。
module Foo
end
命名空間是一種將程式碼分組的方式。
這樣可以避免名稱衝突,也讓人更容易理解程式碼的用途。
當你想存取放在命名空間裡的常數或類別時,可以使用 :: 運算子。
module Foo
class Bar
end
end
Foo::Bar.new
這在許多情況下都很有用,例如多個類別需要相同的「基底」功能,或是程式碼需要在互不相關的類別之間共用。 又或者,你想在彼此沒有關聯的類別之間共用程式碼。
把模組當作混入使用有兩種方式:第一種是使用 include 關鍵字,第二種是使用 extend 關鍵字。
這兩種方法都會讓常數提供給引入或擴充該模組的型別使用。
Include 會讓模組中的所有方法,在引入該模組的型別上以實體方法的形式使用。
include 關鍵字應放在型別的最上方,後面接模組名稱。
module Foo
def foo
"foo"
end
end
class Bar
include Foo
end
Bar.new.foo # => "foo"
Extend 的運作方式和 Include 類似,但它不是讓方法以實體方法的形式使用,而是讓它們以類別方法的形式使用。
extend 關鍵字應寫在型別的最上方,後面接模組名稱。
module Foo
def foo
"foo"
end
end
class Bar
extend Foo
end
Bar.foo # => "foo"
Crystal 中一個常見的模式,是在模組裡使用 extend self 模式。
這會讓模組中的所有方法,在模組本身以類別方法的形式使用。
也就是說,你不需要用 def self.method_name 語法把每個方法都指定給模組。
module Foo
extend self
def foo
"foo"
end
end
Foo.foo # => "foo"