【问题标题】:Map with fat arrow vs colon (Poison - json decode)带有粗箭头与冒号的映射(毒药 - json 解码)
【发布时间】:2017-01-13 09:58:44
【问题描述】:
ab = %{a: 1}
ac = %{"a" => 1}

到底有什么区别?为什么 Poison.decode!返回格式 #2(我需要 #1 与 Ecto.Changeset.change 一起使用)。

Json 响应取自 API,看起来像

[{"a":3}]

【问题讨论】:

    标签: elixir elixir-poison


    【解决方案1】:
    ab = %{a: 1} # atom key you can access it like ab.a
    ac = %{"a" => 1} # string key you can access it ac["a"]
    

    Poison.decode!返回格式#2:

    从广义上讲,来自应用程序外部的数据是不可信的。鉴于原子分配可能导致长期运行的 Erlang 系统中的内存耗尽,因此将原子用于外部数据会使您的应用面临潜在的拒绝服务 (DoS) 攻击。

    这一事实反映在许多 Elixir 库中,例如流行的 JSON 解析器 Poison。表现良好的库在将外部数据转换为内部数据结构时,一般会使用字符串作为映射键

    如果你想将映射键从字符串转换为原子。你可以这样做:

    iex> maps = %{"foo" => "bar"}
    %{"foo" => "bar"}
    iex> for {key, val} <- maps, into: %{}, do: {String.to_atom(key), val}
    %{foo: "bar"}
    

    【讨论】:

    • 使用String.to_existing_atom/1,更安全一些。使用String.to_atom/1 将完全打开此答案中提到的漏洞。
    • 另外,通过原子键访问值,如示例中的ab.a,也可以使用ab[:a] 完成。括号语法是更通用的访问语法,而点语法是可用于映射和结构的糖,当键是原子时。
    猜你喜欢
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2016-08-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    相关资源
    最近更新 更多