vida tutorial también sinonimo programación lenguaje inmortal framework buscó elixir

tutorial - ¿Cómo se verifica el tipo de variable en Elixir?



elixir también se buscó (8)

Acabo de pegar el código de https://elixirforum.com/t/just-created-a-typeof-module/2583/5 :)

defmodule Util do types = ~w[function nil integer binary bitstring list map float atom tuple pid port reference] for type <- types do def typeof(x) when unquote(:"is_#{type}")(x), do: unquote(type) end end

En Elixir, ¿cómo verifica el tipo, como en Python:

>>> a = "test" >>> type(a) <type ''str''> >>> b =10 >>> type(b) <type ''int''>

Leí en Elixir que hay verificadores de tipo como ''is_bitstring'', ''is_float'', ''is_list'', ''is_map'', etc., pero ¿qué pasa si no tiene idea de cuál podría ser el tipo?


Comenzando en elixir 1.2 hay un comando i en iex que enumerará el tipo y más de cualquier variable de Elixir.

iex> foo = "a string" iex> i foo Term "a string" Data type BitString Byte size 8 Description This is a string: a UTF-8 encoded binary. It''s printed surrounded by "double quotes" because all UTF-8 encoded codepoints in it are printable. Raw representation <<97, 32, 115, 116, 114, 105, 110, 103>> Reference modules String, :binary

Si busca en el código el comando i , verá que esto se implementa a través de un protocolo.

https://github.com/elixir-lang/elixir/blob/master/lib/iex/lib/iex/info.ex

Si desea implementar una función para cualquier tipo de Datos en Elixir, la forma de hacerlo es definir un Protocolo e implementar el Protocolo para todos los tipos de datos en los que desea que funcione la función. Desafortunadamente, no puedes usar una función de Protocolo en guardias. Sin embargo, un simple protocolo de "tipo" sería muy sencillo de implementar.


Me encontré con una situación en la que es necesario verificar que el parámetro debe ser cierto tipo. Quizás pueda activarse de una mejor manera.

Me gusta esto:

@required [{"body", "binary"},{"fee", "integer"}, ...] defp match_desire?({value, type}) do apply(Kernel, :"is_#{type}", [value]) end

Uso:

Enum.map(@required, &(match_desire?/1))


No hay forma directa de obtener el tipo de variable en Elixir / Erlang.

Por lo general, desea saber el tipo de una variable para actuar en consecuencia; puede usar las funciones is_* para actuar según el tipo de una variable.

Learn You Some Erlang tiene un buen capítulo sobre escribir en Erlang (y, por lo tanto, en Elixir).

La forma más idiomática de usar la familia de funciones is_* probablemente sería usarlas en coincidencias de patrones:

def my_fun(arg) when is_map(arg), do: ... def my_fun(arg) when is_list(arg), do: ... def my_fun(arg) when is_integer(arg), do: ... # ...and so on


Otro enfoque es utilizar la coincidencia de patrones. Digamos que está utilizando Timex, que utiliza una estructura %DateTime{} , y desea ver si un elemento es uno. Puede encontrar una coincidencia utilizando la coincidencia de patrones en el método.

def is_a_datetime?(%DateTime{}) do true end def is_a_datetime?(_) do false end


Solo dejaré esto aquí por el bien de alguien que, con suerte, descubra una versión realmente sensata. Por el momento no hay buenas respuestas para esto en Google ...

defmodule Util do def typeof(self) do cond do is_float(self) -> "float" is_number(self) -> "number" is_atom(self) -> "atom" is_boolean(self) -> "boolean" is_binary(self) -> "binary" is_function(self) -> "function" is_list(self) -> "list" is_tuple(self) -> "tuple" _ -> "idunno" end end end

En aras de la integridad, los casos de prueba:

cases = [ 1.337, 1337, :''1337'', true, <<1, 3, 3, 7>>, (fn(x) -> x end), {1, 3, 3, 7} ] Enum.each cases, fn(case) -> IO.puts (inspect case) <> " is a " <> (Util.typeof case) end

Aquí hay una solución con protocolos; No estoy seguro de si son más rápidos (seguramente espero que no estén haciendo un bucle sobre todos los tipos), pero es bastante feo (y frágil; si agregan o eliminan un tipo básico o cambian el nombre, lo romperá).

defprotocol Typeable, do: def typeof(self) defimpl Typeable, for: Atom, do: def typeof(_), do: "Atom" defimpl Typeable, for: BitString, do: def typeof(_), do: "BitString" defimpl Typeable, for: Float, do: def typeof(_), do: "Float" defimpl Typeable, for: Function, do: def typeof(_), do: "Function" defimpl Typeable, for: Integer, do: def typeof(_), do: "Integer" defimpl Typeable, for: List, do: def typeof(_), do: "List" defimpl Typeable, for: Map, do: def typeof(_), do: "Map" defimpl Typeable, for: PID, do: def typeof(_), do: "PID" defimpl Typeable, for: Port, do: def typeof(_), do: "Port" defimpl Typeable, for: Reference, do: def typeof(_), do: "Reference" defimpl Typeable, for: Tuple, do: def typeof(_), do: "Tuple" IO.puts Typeable.typeof "Hi" IO.puts Typeable.typeof :ok


Solo porque nadie lo ha mencionado

IO.inspect/1

Salidas para consolar el objeto ... es casi equivalente a JSON.stringify

Muy útil cuando simplemente no puede durante toda su vida descubrir cómo se ve un objeto en una prueba.


También para fines de depuración, si no está en iex, puede llamarlo directamente:

IEx.Info.info(5) => ["Data type": "Integer", "Reference modules": "Integer"]