Elixir - 结构中的大写键

Sim*_*mon 2 json elixir elixir-poison

我正在尝试在Elixir中为API编写一个CLI客户端,以便我可以登录API系统,获取计算所需的数据,然后注销.我已经定义了一个Packet.Login结构,它应该是我在解析我收到的JSON后最终得到的内部数据结构.

我正在使用Poison来解析JSON.问题是,似乎,由于API返回大写属性,我在打印或解析时无法匹配它们,因为Poison将返回带有这些大写键的地图.问题是我似乎不可能使用这样的别名.如果我尝试使用其他语法,

packet[:Token]
Run Code Online (Sandbox Code Playgroud)

它仍然不起作用,而是给我一个错误.但这次关于Packet.Login没有实现Access行为.我能理解这一部分,但不是第一个问题.而我正试图保持代码愚蠢的简单.

defmodule Packet.Login do
  defstruct [:Data, :Token]
end

defimpl String.Chars, for: Packet.Login do
  def to_string(packet) do
    "Packet:\n---Token:\t\t#{packet.Token}\n---Data:\t#{packet.Data}"
  end
end

loginPacket = Poison.decode!(json, as: %Packet.Login{})
IO.puts "#{loginPacket}"
Run Code Online (Sandbox Code Playgroud)

在尝试编译上面的时候我得到了这个:

** (CompileError) lib/packet.ex:31: invalid alias: "packet.Token". If you wanted to define an alias, an alias must expand to an atom at compile time but it did not, you may use Module.concat/2 to build it at runtime. If instead you wanted to invoke a function or access a field, wrap the function or field name in double quotes
(elixir) expanding macro: Kernel.to_string/1
Run Code Online (Sandbox Code Playgroud)

我有办法以某种方式解决这个问题吗?我曾想过解析地图并首先去除所有字段的资本化,但我宁愿不这样做.

为什么我不能拥有结构的大写键?但我似乎可以,只要我不尝试使用它们.

Dog*_*ert 5

为了访问作为以大写字母开头的原子的地图字段,您需要将键放在引号中,例如foo."Bar"或使用括号语法,例如foo[:Bar].foo.Bar在Elixir中解析为别名.对于结构体,您不能使用括号语法,因此最简单的方法是在字段名称周围使用引号.在您的代码中,您需要更改:

"Packet:\n---Token:\t\t#{packet.Token}\n---Data:\t#{packet.Data}"
Run Code Online (Sandbox Code Playgroud)

至:

"Packet:\n---Token:\t\t#{packet."Token"}\n---Data:\t#{packet."Data"}"
Run Code Online (Sandbox Code Playgroud)

我无法在任何地方清楚地找到这个文件,但是Elixir的来源在某些地方提到了这一点,并且还使用这种语法来访问一些:erlang在Elixir中名称不是有效标识符的函数,例如:erlang."=<".


有趣的事实:您可以在Elixir中定义只能使用此引用语法调用的函数:

iex(1)> defmodule Foo do
...(1)>   def unquote(:"!@#")(), do: :ok
...(1)> end
iex(2)> Foo."!@#"()
:ok
Run Code Online (Sandbox Code Playgroud)