跳至內容

巨集方法

巨集定義允許您為類別階層定義一個方法,然後為每個具體子型別實例化該方法。

如果 `def` 包含參照到 `@type` 的巨集表達式,則會隱式將其視為 `macro def`。例如:

class Object
  def instance_vars_names
    {{ @type.instance_vars.map &.name.stringify }}
  end
end

class Person
  def initialize(@name : String, @age : Int32)
  end
end

person = Person.new "John", 30
person.instance_vars_names # => ["name", "age"]

在巨集定義中,引數會以其 AST 節點的形式傳遞,讓您可以在巨集展開中存取它們(`{{some_macro_argument}}`)。然而,對於巨集定義來說並非如此。這裡的參數列表是巨集定義所產生的方法的參數列表。您無法在編譯時存取呼叫引數。

class Object
  def has_instance_var?(name) : Bool
    # We cannot access name inside the macro expansion here,
    # instead we need to use the macro language to construct an array
    # and do the inclusion check at runtime.
    {{ @type.instance_vars.map &.name.stringify }}.includes? name
  end
end

person = Person.new "John", 30
person.has_instance_var?("name")     # => true
person.has_instance_var?("birthday") # => false