답변:
Elixir / Erlang에서 변수 유형을 얻는 직접적인 방법은 없습니다.
일반적으로 변수의 유형을 알고 그에 따라 작동합니다. is_*변수 유형에 따라 작동하기 위해 함수를 사용할 수 있습니다 .
일부 Erlang은 Erlang (및 Elixir) 입력에 관한 장을 제공 합니다.
is_*함수 패밀리 를 사용하는 가장 관용적 인 방법 은 패턴 일치에서 사용하는 것입니다.
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
typeof(variable)?
foo = [1, "hello", [1, 2, 3]]코드를 사용하여 코드 위에 매핑 될 수 없으며 Enum.map(foo, fn(x) -> IO.puts x end), 당신에게 작은 얼굴들을 보여줄 것입니다 (시도하십시오!). 따라서 목록이 목록 인 경우에만 검사가 필요하지만 대부분의 경우 필요하지 않은 경우에도 검사를 사용해야합니다. typeof를 사용하면 if 문 (O (n))을 사전 조회 (O (1))로 바꿀 수 있습니다.
Printable 정수 목록과 같이 인쇄 동작을 래핑하고 변경하는 자체 프로토콜을 구현할 수 있습니다 . Erlang 코드와 함께 사용하지 마십시오. 메시지 대신 정수 목록이 표시되는 이유를 궁금해 할 것입니다.
elixir 1.2부터는 iiex에 유형과 더 많은 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
i명령 의 코드를 보면 이것이 프로토콜을 통해 구현되었음을 알 수 있습니다.
https://github.com/elixir-lang/elixir/blob/master/lib/iex/lib/iex/info.ex
Elixir에서 모든 데이터 유형에 대한 함수를 구현하려는 경우 기능을 수행하려는 모든 데이터 유형에 대한 프로토콜 및 프로토콜 구현을 정의하는 방법입니다. 안타깝게도 경비원에서는 프로토콜 기능을 사용할 수 없습니다. 그러나 간단한 "유형"프로토콜은 구현하기가 매우 간단합니다.
undefined function i/1
&i/1의 기능입니다 IEx.Helpers. &IEx.Helpers.i/1바닐라 엘릭서에 넣으면 에 응용 프로그램으로 CompileError포함되지 않은 경우를 생성 :iex합니다 mix.exs.
또 다른 방법은 패턴 일치를 사용하는 것입니다. %DateTime{}구조체 를 사용하는 Timex를 사용하고 있고 요소가 하나인지 알고 싶다고 가정 해보십시오 . 메소드에서 패턴 일치를 사용하여 일치를 찾을 수 있습니다.
def is_a_datetime?(%DateTime{}) do
true
end
def is_a_datetime?(_) do
false
end
switch/가 아닌 패턴 일치에 따라 작동 case합니다.
누군가가 실제로 제정신 버전을 알아 내기 위해 여기에 남겨 두겠습니다. 현재 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"
true -> "idunno"
end
end
end
완전성을 위해 테스트 사례 :
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
프로토콜이있는 솔루션은 다음과 같습니다. 나는 그들이 더 빠르면 확실하지 않습니다 (모든 유형에 대해 루프를 수행하지 않기를 바랍니다). 그러나 그것은 매우 추악합니다 (깨지기 쉽습니다; 기본 유형을 추가하거나 제거하거나 이름을 바꾸면 깨질 것입니다).
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
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
아무도 언급하지 않았기 때문에
IO.inspect/1
객체를 콘솔로 출력합니다 ... JSON과 거의 같습니다.
당신의 인생을 테스트 할 때 물체가 어떻게 보이는지 알아낼 수 없을 때 매우 유용합니다.