How to check if the Map is also a Structure?

In Elixir, I can check if a variable is mapor struct, by calling Kernel.is_map/1, which makes sense, because Structures are the cards below , but I would like to distinguish between them. I know that I can call __struct__Struct to get its module name, but calling it on a regular map:

** (KeyError) key :__struct__ not found in: %{}

So my question is: How to check if a variable is a map or a structure?


Usage example:

# I want to handle struct and map inputs differently in my Module

defmodule DifferentThings do
  def do_something(arg) when is_map(arg) do
    # Do something with Maps
  end

  def do_something(arg) when is_struct(arg) do
    # But handle Structs differently
    # Issue is, `is_struct` does not exist
  end
end
+4
source share
4 answers

In general, check if map is a structure:

Map.has_key?(struct, :__struct__)

For different method declarations (more general method two):

defmodule DifferentThings do
  def do_something(%{__struct__: _} = arg) do
    # ...
  end

  def do_something(arg) when is_map(arg) do
    # ...
  end
end
+12
source

,

defmodule DifferentThings do
  def do_something(arg = %_x{}) do
    IO.puts "This is a struct"
  end

  def do_something(arg = %{}) do
    IO.puts "This is a map"
  end
end
+5

Map vs Struct , .

defmodule Guard do

  def foo(%{:__struct__ => x })  do
    Struct
  end

  def foo(x) when is_map x do
    Map
  end

end
+3

keys Map.keys/1.

map struct is_map/1 true, :

Map.keys(%{}) will return []

Map.keys(struct) 

, . [:__struct__, :name, :age].

, :

:__struct__ in Map.keys(struct).

, is_struct .

+2

Source: https://habr.com/ru/post/1656150/


All Articles