在Elixir中,如何检查Python中的类型:
>>> a = "test"
>>> type(a)
>>> b =10
>>> type(b)
我在Elixir中读到了类型检查器,例如'is_bitstring','is_float','is_list','is_map'等,但如果您不知道该类型是什么呢?
1> Fred the Mag..:
从elixir 1.2开始,i
在iex中有一个命令,它将列出任何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中的任何数据类型实现函数,那么执行此操作的方法是为希望函数处理的所有数据类型定义协议和协议实现.不幸的是,你不能在守卫中使用协议功能.但是,简单的"类型"协议实现起来非常简单.
2> whatyouhide..:
在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
Erlang/Elixir真的没有存储的类型信息吗?我是否真的需要在现有类型上创建一个全新的包装器才能使用该语言?吴
@Dmitry可用表示什么?我可以看到一个具体的示例,在该示例中您将使用`typeof(variable)`之类的结果吗?
更具体; typeof最有用的用法是将[type string,function]的哈希表直接映射到未知数列表.例如; IO.puts不能映射到`foo = [1,"hello",[1,2,3]]`,代码为&#39;Enum.map(foo,fn(x) - > IO.puts x end) `因为[1,2,3]将被读作字符(为什么是erlang !!?),并会向你展示一堆笑脸(试试吧!).所以我们被迫使用检查,即使只是列表需要检查,否则大部分时间我们都不需要检查.typeof让我们将if语句(O(n))转换为字典查找(O(1)).
3> atomkirk..:
同样出于调试目的,如果你不在iex中,你可以直接调用它:
IEx.Info.info(5)
=> ["Data type": "Integer", "Reference modules": "Integer"]
4> popedotninja..:
另一种方法是使用模式匹配.假设您正在使用Timex,它使用%DateTime{}
结构,并且您想要查看元素是否为1.您可以在方法中使用模式匹配找到匹配项.
def is_a_datetime?(%DateTime{}) do
true
end
def is_a_datetime?(_) do
false
end
5> Dmitry..:
我会把这个放在这里,以便有人希望找出一个真正理智的版本.目前谷歌上没有这个好消息的答案......
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
6> user3197999..:
我只是粘贴来自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