檢查變量的類型在藥劑你如何檢查類型,如在Python:如何在藥劑
>>> a = "test"
>>> type(a)
<type 'str'>
>>> b =10
>>> type(b)
<type 'int'>
我在花好月圓閱讀有類型檢查,如「is_bitstring」,「is_float ','is_list','is_map'等,但如果您不知道類型可能是什麼?
檢查變量的類型在藥劑你如何檢查類型,如在Python:如何在藥劑
>>> a = "test"
>>> type(a)
<type 'str'>
>>> b =10
>>> type(b)
<type 'int'>
我在花好月圓閱讀有類型檢查,如「is_bitstring」,「is_float ','is_list','is_map'等,但如果您不知道類型可能是什麼?
沒有直接的方法可以在Elixir/Erlang中獲得變量的類型。
您通常想知道變量的類型以便相應地執行;您可以使用is_*
函數來根據變量的類型進行操作。
瞭解你Erlang有a nice chapter關於打入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
在靈藥1.2開始出現在IEX的i
命令將列出類型多任何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
如果要實現在花好月圓任何數據類型的功能,做到這一點的方法是定義該協議的協議和實現你想要的功能上工作的所有數據類型。不幸的是,你不能在守衛中使用協議功能。但是,一個簡單的「類型」協議可以非常直接地實現。
這應該是被接受的答案。 – 2017-01-29 15:55:17
另一種方法是使用模式匹配。假設您使用Timex,它使用%DateTime{}
結構,並且您想要查看某個元素是否爲一個。您可以在方法中使用模式匹配找到匹配項。
def is_a_datetime?(%DateTime{}) do
true
end
def is_a_datetime?(_) do
false
end
我會在這裏留下這個爲了有人希望搞清楚一個實際的理智版本。目前沒有很好的回答這個即將在谷歌...
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
爲了完整起見,測試案例:
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
而且粘貼代碼進行調試,如果你在IEX是不是,你可以直接把它叫做:
IEx.Info.info(5)
=> ["Data type": "Integer", "Reference modules": "Integer"]
我遇到了一個需要檢查參數需要確定類型的情況。也許可以採取更好的方式。
像這樣:
@required [{"body", "binary"},{"fee", "integer"}, ...]
defp match_desire?({value, type}) do
apply(Kernel, :"is_#{type}", [value])
end
用法:
Enum.map(@required, &(match_desire?/1))
請忽略我,我發現更好的方法已經提供... – Bingoabs 2017-10-30 02:56:11
是否二郎/靈藥真的沒有存儲類型的信息?我是否真的需要爲現有的語言創建一個全新的包裝來使語言可用? O.o – Dmitry 2016-11-24 03:02:48
@Dmitry你可用的意思是什麼?我能看到一個具體的例子,你可以使用類似'typeof(variable)'的結果嗎? – whatyouhide 2016-11-25 09:49:42
當程序離開編譯時間並進入運行時時,關於某個對象的所有信息都將丟失。當我想要檢查正在運行的程序的信息時,知道發生了什麼的唯一方法就是檢查通過地圖網絡公開的事物。如果類型信息不可用,並且我想要檢查類型,則分析對象以獲取其類型的成本遠高於類型已經暴露的情況。 typeof允許我們分析正在運行的系統,並在運行時以允許類型檢查和多態性的方式對其進行擴展。 – Dmitry 2016-11-25 10:10:53