LoginSignup
12
1

Behaviourで共通の機能を実装する

Last updated at Posted at 2023-12-06

Behaviourで共通の機能を実装する

ElixirにはBehaviourという機能があり、共有する機能(関数)を定義することができる。

定義したBehaviourをモジュールに実装することで、定義に沿った関数の実装を行うことができる。

Behaviourの定義

Behaviourを定義する際には通常のモジュールの作成に加え、@callbackによって共有する関数の名前と戻り値を定義する。

defmodule Action do
  @callback say(name: String.t()) :: String.t()
end

Behaviourの実装

定義したBehaviourを他のモジュールに実装するためには、@behaviourによって実装するBehaviourを指定する。

defmodule Dog do
  @behaviour Action

  def say(name), do: "#{name}: わんわん!"
end

実装するモジュールで構造体を定義した場合

Elixirの構造体はモジュールであるため、構造体の定義と一緒に記述することができる。

defmodule Cat do
  defstruct [:name]
  @behaviour Action

  def say(name), do: "#{name}: にゃーん!"
end

しかしこの場合は「構造体にBehaivourを実装している」とは言わない。

まずElixirの構造体は、Rustなどの構造体とは全く異なるものものである。

Rustの構造体は、traitimplによって共通の関数を実装することができるので、
オブジェクト指向言語のクラスに近い使い方をすると言える。

これに対してElixirの構造体は、定義されたキーを持つマップである。

つまりインスタンス = %構造体{}から生成したインスタンスはマップであり、そのためインスタンス.関数()のように関数を呼び出すことができない。

よってElixirではモジュールから関数を呼び出すことはできるが、構造体から呼び出すことはできない。

それは、構造体のフィールドへのアクセスが構造体.キーであり、マップから関数を呼び出せないからでもある。

またそれはis_map(インスタンス)を実行することで理解することができる。

12
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
1