Elixir模块属性 #
一、属性基础 #
1.1 定义属性 #
elixir
defmodule Example do
@name "MyModule"
@version "1.0.0"
def info do
"Module: #{@name}, Version: #{@version}"
end
end
1.2 读取属性 #
elixir
iex(1)> defmodule Example do
...> @value 42
...> def get_value, do: @value
...> end
iex(2)> Example.get_value()
42
1.3 属性特性 #
- 属性在编译时求值
- 属性值在编译后不可变
- 每次读取属性都会内联其值
二、内置属性 #
2.1 文档属性 #
elixir
defmodule User do
@moduledoc """
User management module.
This module provides functions for managing users.
"""
@doc """
Creates a new user.
## Parameters
- `name` - User name
- `email` - User email
## Examples
iex> User.new("Alice", "alice@example.com")
%User{name: "Alice", email: "alice@example.com"}
"""
def new(name, email) do
%{name: name, email: email}
end
end
2.2 类型属性 #
elixir
defmodule User do
@type t :: %__MODULE__{
id: integer(),
name: String.t(),
email: String.t()
}
@type name :: String.t()
@type email :: String.t()
defstruct [:id, :name, :email]
end
2.3 规范属性 #
elixir
defmodule Math do
@spec add(number(), number()) :: number()
def add(a, b), do: a + b
@spec divide(number(), number()) :: {:ok, number()} | {:error, :division_by_zero}
def divide(_, 0), do: {:error, :division_by_zero}
def divide(a, b), do: {:ok, a / b}
end
2.4 行为属性 #
elixir
defmodule MyGenServer do
@behaviour GenServer
def init(args), do: {:ok, args}
def handle_call(_msg, _from, state), do: {:reply, :ok, state}
def handle_cast(_msg, state), do: {:noreply, state}
end
三、累积属性 #
3.1 累积列表 #
elixir
defmodule Router do
@routes []
def route(path, handler) do
@routes [{path, handler} | @routes]
end
def routes, do: @routes
end
3.2 注册回调 #
elixir
defmodule Plugin do
@callbacks []
def register_callback(name, func) do
@callbacks [{name, func} | @callbacks]
end
def callbacks, do: @routes
end
3.3 使用示例 #
elixir
defmodule MyPlugin do
Plugin.register_callback(:before_save, fn data -> data end)
Plugin.register_callback(:after_save, fn data -> IO.puts("Saved") end)
end
四、编译时钩子 #
4.1 @before_compile #
elixir
defmodule MyModule do
@before_compile MyModule
defmacro __before_compile__(_env) do
quote do
def generated_function, do: "I was generated!"
end
end
end
4.2 @after_compile #
elixir
defmodule MyModule do
@after_compile __MODULE__
def __after_compile__(_env, _bytecode) do
IO.puts("Module compiled!")
end
end
4.3 @on_definition #
elixir
defmodule Tracer do
@on_definition {Tracer, :trace}
def trace(_env, :def, name, args, _guards, _body) do
IO.puts("Defined function #{name}/#{length(args)}")
end
def trace(_env, :defp, name, args, _guards, _body) do
IO.puts("Defined private function #{name}/#{length(args)}")
end
def trace(_, _, _, _, _, _), do: :ok
def public_func(a, b), do: a + b
defp private_func(a), do: a * 2
end
五、外部资源 #
5.1 @external_resource #
elixir
defmodule Config do
@external_resource Path.join([__DIR__, "config.json"])
@config File.read!(Path.join([__DIR__, "config.json"]))
|> Jason.decode!()
def get(key), do: Map.get(@config, key)
end
5.2 重新编译 #
当外部资源改变时,模块会重新编译。
六、编译选项 #
6.1 @compile #
elixir
defmodule Optimized do
@compile {:inline, my_func: 1}
def my_func(x), do: x * 2
end
6.2 常用选项 #
elixir
@compile :nowarn_unused_vars
@compile {:nowarn_unused_vars, true}
@compile {:inline, func: 1}
@compile {:autoload, false}
七、模块信息 #
7.1 获取模块信息 #
elixir
iex(1)> defmodule Example do
...> @author "Developer"
...> def info, do: __MODULE__.__info__(:attributes)
...> end
iex(2)> Example.info()
[author: "Developer"]
7.2 __info__选项 #
elixir
__MODULE__.__info__(:functions)
__MODULE__.__info__(:macros)
__MODULE__.__info__(:module)
__MODULE__.__info__(:attributes)
__MODULE__.__info__(:compile)
八、属性最佳实践 #
8.1 常量定义 #
elixir
defmodule Constants do
@pi 3.14159265359
@e 2.71828182846
@golden_ratio 1.61803398875
def pi, do: @pi
def e, do: @e
def golden_ratio, do: @golden_ratio
end
8.2 配置管理 #
elixir
defmodule AppConfig do
@app_name Application.compile_env(:my_app, :name, "MyApp")
@version Application.compile_env(:my_app, :version, "0.1.0")
@env Application.compile_env(:my_app, :env, :dev)
def app_name, do: @app_name
def version, do: @version
def env, do: @env
end
8.3 元数据注册 #
elixir
defmodule Task do
@tasks %{}
def register(name, func) do
@tasks Map.put(@tasks, name, func)
end
def get(name), do: Map.get(@tasks, name)
def all, do: @tasks
end
九、属性列表 #
| 属性 | 用途 |
|---|---|
@moduledoc |
模块文档 |
@doc |
函数文档 |
@spec |
类型规范 |
@type |
类型定义 |
@typep |
私有类型 |
@opaque |
不透明类型 |
@callback |
回调规范 |
@macrocallback |
宏回调 |
@behaviour |
行为实现 |
@before_compile |
编译前钩子 |
@after_compile |
编译后钩子 |
@on_definition |
定义钩子 |
@external_resource |
外部资源 |
@compile |
编译选项 |
@derive |
协议派生 |
@enforce_keys |
强制键 |
十、总结 #
本章学习了:
| 特性 | 用途 |
|---|---|
| 自定义属性 | 存储常量和元数据 |
| 累积属性 | 收集多个值 |
| 编译钩子 | 编译时代码生成 |
| 内置属性 | 文档、类型、规范 |
准备好学习并发编程了吗?让我们进入下一章。
最后更新:2026-03-27