【问题标题】:Protocol Enumerable not implemented for struct. How to convert the struct into an enumerable?未为结构实现协议可枚举。如何将结构转换为可枚举?
【发布时间】:2016-02-29 11:21:18
【问题描述】:

我正在使用结构在 Phoenix / Elixir 应用程序中创建自定义模型。像这样:

defmodule MyApp.User do
  defstruct username: nil, email: nil, password: nil, hashed_password: nil
end

new_user = %MyApp.User{email: "email@example.com", hashed_password: nil, password: "secret", username: "ole"}

为了将它与我的数据库适配器一起使用,我需要数据是可枚举的。结构显然不是。至少我收到这个错误:

(Protocol.UndefinedError) protocol Enumerable not implemented for %MyApp.User{ ...

所以我用理解来试试运气。这当然也不起作用,因为结构不可枚举(愚蠢的我)

enumberable_user = for {key, val} <- new_user, into: %{}, do: {key, val}

如何将数据转换为可枚举的地图?

【问题讨论】:

    标签: erlang elixir phoenix-framework


    【解决方案1】:

    您可以使用Map.from_struct/1 在插入数据库时​​转换为地图。这将删除 __struct__ 键。

    您曾经能够派生 Enumerable 协议,但似乎是偶然的。 https://github.com/elixir-lang/elixir/issues/3821

    哎呀,之前推导工作是个意外,我认为我们不应该修复它。也许我们可以更新 v1.1 更改日志以使其清楚,但我不会更改代码。

    defmodule User do
      @derive [Enumerable]
      defstruct name: "", age: 0
    end
    
    Enum.each %User{name: "jose"}, fn {k, v} ->
      IO.puts "Got #{k}: #{v}"
    end
    

    【讨论】:

      【解决方案2】:

      我创建了模块 make_enumerable 来解决这个问题:

      defmodule Bar do
        use MakeEnumerable
        defstruct foo: "a", baz: 10
      end
      
      iex> import Bar
      iex> Enum.map(%Bar{}, fn({k, v}) -> {k, v} end)
      [baz: 10, foo: "a"]
      

      【讨论】:

        猜你喜欢
        • 2018-05-22
        • 2018-07-28
        • 2016-05-09
        • 2016-04-26
        • 2014-07-04
        • 2023-01-03
        • 2021-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多