Elixir语法基础 #

一、注释 #

1.1 单行注释 #

Elixir只支持单行注释,使用 # 开头:

elixir
IO.puts("Hello")
IO.puts("World")

1.2 内联注释 #

elixir
x = 10
result = x * 2

1.3 文档注释 #

Elixir使用模块属性提供文档:

elixir
defmodule MyModule do
  @moduledoc """
  模块文档

  这里写模块的详细说明。
  """

  @doc """
  函数文档

  ## 参数

    - `name` - 用户名称

  ## 示例

      iex> MyModule.greet("World")
      "Hello, World!"

  """
  def greet(name) do
    "Hello, #{name}!"
  end
end

1.4 查看文档 #

elixir
iex(1)> h(MyModule)
iex(2)> h(MyModule.greet/1)

二、标识符命名规则 #

2.1 变量命名 #

  • 必须以小写字母或下划线开头
  • 可以包含字母、数字和下划线
  • 推荐使用snake_case
elixir
name = "Alice"
user_name = "Bob"
_private_var = "internal"

2.2 原子命名 #

  • 以冒号开头,或以大写字母开头
  • 可以包含字母、数字、下划线和@
elixir
:ok
:error
:user_name
:true
:false
:nil

2.3 模块命名 #

  • 使用PascalCase(大驼峰)
  • 可以使用点号分隔命名空间
elixir
defmodule MyApp.User do
end

defmodule MyApp.Accounts.User do
end

2.4 函数命名 #

  • 使用snake_case
  • 可以以 ? 结尾表示布尔返回
  • 可以以 ! 结尾表示可能抛出异常
elixir
def calculate_total(price, quantity) do
  price * quantity
end

def valid?(data) do
  data != nil
end

def parse!(string) do
  case Integer.parse(string) do
    {number, ""} -> number
    _ -> raise "Invalid integer: #{string}"
  end
end

2.5 宏命名 #

宏通常使用snake_case,但特殊情况可以使用其他形式:

elixir
defmacro my_macro do
  quote do
    IO.puts("This is a macro")
  end
end

三、运算符 #

3.1 算术运算符 #

elixir
iex(1)> 1 + 2
3

iex(2)> 5 - 3
2

iex(3)> 3 * 4
12

iex(4)> 10 / 2
5.0

iex(5)> div(10, 3)
3

iex(6)> rem(10, 3)
1

注意:/ 总是返回浮点数,使用 div/2 获取整数除法。

3.2 比较运算符 #

elixir
iex(1)> 1 == 1
true

iex(2)> 1 != 2
true

iex(3)> 1 < 2
true

iex(4)> 1 <= 1
true

iex(5)> 1 > 0
true

iex(6)> 1 >= 1
true

严格比较运算符:

elixir
iex(1)> 1 === 1
true

iex(2)> 1 === 1.0
false

iex(3)> 1 !== 1.0
true

3.3 逻辑运算符 #

elixir
iex(1)> true and false
false

iex(2)> true or false
true

iex(3)> not true
false

短路运算符(处理非布尔值):

elixir
iex(1)> nil && 1
nil

iex(2)> 1 && 2
2

iex(3)> nil || 1
1

iex(4)> false || 1
1

iex(5)> !nil
true

iex(6)> !1
false

3.4 字符串运算符 #

elixir
iex(1)> "Hello, " <> "World!"
"Hello, World!"

iex(2)> "Hello" in ["Hello", "World"]
true

3.5 列表运算符 #

elixir
iex(1)> [1, 2] ++ [3, 4]
[1, 2, 3, 4]

iex(2)> [1, 2, 3, 2, 1] -- [2, 1]
[1, 3, 2]

iex(3)> 1 in [1, 2, 3]
true

3.6 映射运算符 #

elixir
iex(1)> map = %{a: 1, b: 2}
%{a: 1, b: 2}

iex(2)> map.a
1

iex(3)> map[:a]
1

iex(4)> %{map | a: 10}
%{a: 10, b: 2}

3.7 管道运算符 #

管道运算符 |> 将左边表达式的结果作为右边函数的第一个参数:

elixir
iex(1)> "hello" |> String.upcase() |> String.reverse()
"OLLEH"

等价于:

elixir
String.reverse(String.upcase("hello"))

3.8 运算符优先级 #

从高到低:

优先级 运算符
1 .(点号访问)
2 @(模块属性)
3 ^(钉住操作符)
4 + - ! not(一元)
5 **
6 * /
7 + -
8 ++ -- .. <>
9 in not in
10 `
11 < > <= >=
12 == != =~ === !==
13 && and
14 || or
15 =
16 =>
17 |

四、基本数据类型 #

4.1 整数 #

elixir
iex(1)> 42
42

iex(2)> 0xFF
255

iex(3)> 0o644
420

iex(4)> 0b1010
10

iex(5)> 1_000_000
1000000

4.2 浮点数 #

elixir
iex(1)> 3.14
3.14

iex(2)> 1.0e-10
1.0e-10

4.3 原子 #

原子是常量,名称就是值:

elixir
iex(1)> :hello
:hello

iex(2)> :true
true

iex(3)> :false
false

iex(4)> :nil
nil

4.4 布尔值 #

elixir
iex(1)> true
true

iex(2)> false
false

iex(3)> is_boolean(true)
true

iex(4)> is_boolean(:true)
true

4.5 字符串 #

elixir
iex(1)> "Hello, World!"
"Hello, World!"

iex(2)> "Hello\nWorld"
"Hello\nWorld"

iex(3)> """
...> Multi-line
...> String
...> """
"Multi-line\nString\n"

五、代码块 #

5.1 do-end块 #

elixir
if true do
  IO.puts("True!")
end

5.2 关键字语法 #

elixir
if true, do: IO.puts("True!")

5.3 多行关键字语法 #

elixir
if true do
  IO.puts("True!")
else
  IO.puts("False!")
end

六、代码规范 #

6.1 格式化工具 #

使用 mix format 自动格式化代码:

bash
mix format

配置 .formatter.exs

elixir
[
  inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
  line_length: 98
]

6.2 模块组织 #

elixir
defmodule MyApp.User do
  @moduledoc """
  User module documentation.
  """

  alias MyApp.Accounts
  alias MyApp.Posts

  import Ecto.Query

  defstruct [:id, :name, :email]

  @type t :: %__MODULE__{
    id: integer(),
    name: String.t(),
    email: String.t()
  }

  @doc "Creates a new user"
  def new(attrs) do
    struct(__MODULE__, attrs)
  end
end

6.3 函数组织顺序 #

  1. defstruct
  2. @type
  3. @doc
  4. 公共函数
  5. 私有函数

6.4 命名约定 #

类型 约定 示例
变量 snake_case user_name
函数 snake_case calculate_total
模块 PascalCase UserAccount
原子 snake_case :user_name
文件名 snake_case user_account.ex

6.5 行长度限制 #

推荐每行不超过98个字符。

6.6 管道操作符规范 #

elixir
list
|> Enum.map(&(&1 * 2))
|> Enum.filter(&(&1 > 5))
|> Enum.sum()

七、作用域 #

7.1 变量作用域 #

elixir
x = 1

if true do
  x = 2
  IO.puts(x)
end

IO.puts(x)

7.2 块作用域 #

elixir
case {1, 2, 3} do
  {1, x, 3} ->
    IO.puts(x)
  _ ->
    IO.puts("No match")
end

7.3 函数作用域 #

elixir
defmodule Example do
  def foo do
    x = 1
    bar()
  end

  def bar do
  end
end

八、总结 #

本章学习了:

  • 注释和文档注释
  • 标识符命名规则
  • 各种运算符
  • 运算符优先级
  • 代码格式化规范
  • 作用域规则

准备好学习数据类型了吗?让我们进入下一章。

最后更新:2026-03-27