【问题标题】:Elixir Dialyzer error when accessing struct prop using dot syntax使用点语法访问 struct prop 时出现 Elixir Dialyzer 错误
【发布时间】:2021-06-25 17:19:56
【问题描述】:

更新我的项目以使用 Elixir 1.12 我注意到 Dialyzer 抱怨某些地方我使用点符号访问了结构的属性。例如,这是我的应用程序中的一个 graphql 解析器函数:

def update(_root, %{input: input}, %{context: %{current_user: user}}) do
  case user
        |> User.update_changeset(input)
        |> Repo.update() do
    {:ok, updated_user} ->
      if user.email !== updated_user.email do
        Email.email_changed(user.email, updated_user.email)
        |> Mailer.deliver_later()
      end

      {:ok, updated_user}

    err ->
      err
  end
end

Dialyser 已突出显示表达式 user.email !== updated_user.email 并出现以下错误:

The call _.'email'/() requires that _@1 is of type atom(), not {map(), map()}

知道这个错误是什么意思以及如何解决它吗?

(这一切都编译并运行良好,我只是想知道为什么它似乎不能满足 Dialyzer)

【问题讨论】:

    标签: elixir dialyzer


    【解决方案1】:

    虽然很难判断 是否错误,或者您的代码是否存在导致此问题的故障,但在传递给此函数之前不了解上下文是如何构建的,但有一些一般性建议。

    在各处使用深度模式匹配来缩小问题范围。

    def update(_root, %{input: input},
      %{context: %{current_user: %User{email: email}}}) do
        user
        |> User.update_changeset(input)
        |> Repo.update() 
        |> case do
          {:ok, %User{email: ^email} = user} ->
            {:ok, user}
    
          {:ok, %User{email: updated_email} = user} ->
            email
            |> Email.email_changed(updated_email)
            |> Mailer.deliver_later()
    
            {:ok, user}
    
          err ->
            err
        end
    end
    

    这样代码更清晰,意图更清晰,错误(如果发生)更明显,并粘在它实际所属的位置。

    【讨论】:

    • 这是一个公平的评论,但无论如何我都需要使用整个user,因此我没有解构整个事情(即使有人可以做类似%{context: %{current_user: user = %User{email: email}}} 的事情,但这得到了相当冗长)。 FWIW,这确实使透析器错误消失了。不过,我对错误的含义更感兴趣。
    • 那么请至少显示update/3 的规格。事实证明,dialyzer 无法正确获取上下文类型。
    • 很公平,是的,我认为这是 Dialyzer 没有足够的信息来知道 user 的类型的问题,所以它猜测。在模式匹配中添加一些提示可以解决它。
    • 请注意我是如何通过直接模式匹配摆脱if/2 的,这使得代码更加地道:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 2012-05-11
    相关资源
    最近更新 更多