Kurzusok
/
Elixir
Elixir
/
Tanterv
/
Viselkedések
Vi

Viselkedések ebben a kurzusban: Elixir

1 feladat

A(z) Viselkedések fogalomról

A viselkedésekkel interfészeket (függvények és makrók halmazát) definiálhatunk egy viselkedésmodulban. Ezeket az interfészeket később különböző callback modulok valósíthatják meg. A közös interfésznek köszönhetően ezek a callback modulok felcserélhetően használhatók.

Note

Figyeld meg: a „behaviours” szót brit helyesírással írjuk.

Viselkedések definiálása

Egy viselkedés definiálásához létre kell hoznunk egy új modult, és meg kell adnunk azon függvények listáját, amelyek a kívánt interfész részét képezik. Minden függvényt a @callback modulattribútummal kell definiálni. A szintaxis ugyanaz, mint egy függvény típusspecifikáció esetében (@spec). Meg kell adnunk a függvény nevét, az argumentumtípusok listáját és az összes lehetséges visszatérési típust.

defmodule Countable do
  @callback count(collection :: any) :: pos_integer
end

Viselkedések implementálása

Ha egy létező viselkedést szeretnénk hozzáadni a modulunkhoz (azaz callback modult hozunk létre), a @behaviour modulattribútumot használjuk. Az értéke annak a viselkedésmodulnak a neve, amelyet hozzáadunk.

Ezután definiálnunk kell minden olyan függvényt (callbacket), amelyet az adott viselkedésmodul megkövetel. Ha valaki más viselkedését implementáljuk, például az Elixir beépített Access vagy GenServer viselkedését, a viselkedéshez tartozó összes callback listáját a hexdocs.pm dokumentációjában találjuk.

Egy callback modul nem korlátozódik arra, hogy csak a viselkedésének részét képező függvényeket implementálja. Egyetlen modul akár több viselkedést is implementálhat.

Ahhoz, hogy megjelöljük, melyik függvény melyik viselkedésből származik, minden függvény elé oda kell írnunk a @impl modulattribútumot. Az értéke pedig annak a viselkedésmodulnak a neve, amely ezt a callbacket definiálja.

defmodule BookCollection do
  @behaviour Countable

  defstruct [:list, :owner]

  @impl Countable
  def count(collection) do
    Enum.count(collection.list)
  end

  def mark_as_read(collection, book) do
    # other function unrelated to the Countable behaviour
  end
end

Alapértelmezett callback-implementációk

Amikor viselkedést definiálunk, megadhatjuk egy callback alapértelmezett implementációját is. Ezt az implementációt a __using__/1 makró idézett kifejezésében kell megadni. Ahhoz, hogy a viselkedésmodul használói felülírhassák az alapértelmezett implementációt, a függvény implementációja után hívd meg a defoverridable/1 makrót. Ez egy kulcsszólistát vár, amelyben a kulcsok a függvénynevek, az értékek pedig a függvények aritásai.

defmodule Countable do
  @callback count(collection :: any) :: pos_integer

  defmacro __using__(_) do
    quote do
      @behaviour Countable
      def count(collection), do: Enum.count(collection)
      defoverridable count: 1
    end
  end
end

Ne feledd, hogy a __using__/1 makrón belül függvényeket definiálni csak az alapértelmezett callback-implementációk megadása céljából ajánlott, más célra nem. A függvényeket viszont mindig definiálhatod egy másik modulban, és importálhatod őket a __using__/1 makróban.

Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg

Tanuld meg a(z) Viselkedések fogalmat