Erlang/Elixir代码类型分析技能Skill dialyzer-analysis

该技能专注于使用 Dialyzer 工具对 Erlang 和 Elixir 代码进行静态类型分析、警告检测和修复,提升代码质量和开发效率,适用于软件测试和代码优化场景。关键词:Dialyzer、类型分析、Erlang、Elixir、静态分析、代码警告、软件测试、编程工具。

测试 0 次安装 0 次浏览 更新于 3/25/2026

名称: dialyzer-analysis 用户可调用: false 描述: 用于分析和修复 Erlang/Elixir 代码中的 Dialyzer 警告和类型差异。 允许工具: []

Dialyzer 分析

理解并修复 Erlang 和 Elixir 代码中的 Dialyzer 警告。

类型规范

基本规范

@spec add(integer(), integer()) :: integer()
def add(a, b), do: a + b

@spec get_user(pos_integer()) :: {:ok, User.t()} | {:error, atom()}
def get_user(id) do
  # 实现
end

复杂类型

@type user :: %{
  id: pos_integer(),
  name: String.t(),
  email: String.t(),
  role: :admin | :user | :guest
}

@spec process_users([user()]) :: {:ok, [user()]} | {:error, String.t()}

泛型类型

@spec map_values(map(), (any() -> any())) :: map()
@spec filter_list([t], (t -> boolean())) :: [t] when t: any()

常见警告

模式匹配覆盖

# 警告:模式匹配不完整
case value do
  :ok -> :success
  # 缺少 :error 情况
end

# 修复后
case value do
  :ok -> :success
  :error -> :failure
  _ -> :unknown
end

无返回

# 警告:函数没有局部返回
def always_raises do
  raise "error"
end

# 使用规范修复
@spec always_raises :: no_return()
def always_raises do
  raise "error"
end

未匹配的返回

# 警告:未匹配的返回
def process do
  {:error, "failed"}  # 返回值未使用
  :ok
end

# 修复后
def process do
  case do_something() do
    {:error, reason} -> handle_error(reason)
    :ok -> :ok
  end
end

未知函数

# 警告:未知函数
SomeModule.undefined_function()

# 修复:确保函数存在或动态处理
if Code.ensure_loaded?(SomeModule) and
   function_exported?(SomeModule, :function_name, 1) do
  SomeModule.function_name(arg)
end

类型分析模式

联合类型

@type result :: :ok | {:ok, any()} | {:error, String.t()}

@spec handle_result(result()) :: any()
def handle_result(:ok), do: nil
def handle_result({:ok, value}), do: value
def handle_result({:error, msg}), do: Logger.error(msg)

不透明类型

@opaque internal_state :: %{data: map(), timestamp: integer()}

@spec new() :: internal_state()
def new, do: %{data: %{}, timestamp: System.system_time()}

远程类型

@spec process_conn(Plug.Conn.t()) :: Plug.Conn.t()
@spec format_date(Date.t()) :: String.t()

成功类型

Dialyzer 使用成功类型:

  • 近似函数可以成功执行的内容
  • 与传统类型系统不同
  • 可能遗漏一些错误,但理论上没有误报

示例

# Dialyzer 推断:integer() -> integer()
def double(x), do: x * 2

# 更具体的规范
@spec double(pos_integer()) :: pos_integer()
def double(x) when x > 0, do: x * 2

最佳实践

  1. 从核心模块开始:首先为公共 API 添加规范
  2. 使用严格类型:优先选择特定类型而非 any()
  3. 文档化假设:使用规范记录预期行为
  4. 测试规范:确保规范与实际行为匹配
  5. 迭代修复:逐步修复警告

调试技巧

详细输出

mix dialyzer --format dialyzer

解释警告

mix dialyzer --explain

检查特定文件

mix dialyzer lib/my_module.ex