模块 04查看课程目录
00起跑线:两门语言,一台机器01先建立 BEAM 心智模型02Elixir 基础:让数据流过函数03Erlang 基础:读懂 BEAM 的母语04两种语法,一套语义05从裸进程理解并发06从手写循环推导 OTP07监督树与应用08状态、吞吐与背压09分布式与可运维性10Erlang ↔ Elixir 互操作11综合项目:可靠任务调度器
04
桥接进阶入门ElixirErlangBEAM

两种语法,一套语义

把语法糖剥开,建立一张长期可用的互译表。

4检查点
5 小时预计完成
为什么先学这个

先修正心智模型,再增加 API

如果把两门语言分别背一遍,你会重复学习并在互操作时迷失。更高效的方法是只讲一次 BEAM 语义,再明确语法映射与少数真实差异:协议/behaviour 表达、字符串约定、异常语法、工具链。

学完你能做到

可验证的学习目标

  • 能在常见数据、函数和模块调用之间双向翻译
  • 能区分 Elixir 语法便利与 BEAM 底层语义
  • 能用 spec 与测试固定跨语言协议
前置知识
  • 完成 Elixir 与 Erlang 基础
  • 会写纯函数测试
最小心智模型

先抓住三个词

01

atom 映射

Elixir 的 `:ok` 与 Erlang 的 `ok` 是同一个 atom;Elixir 模块名本身也是带 `Elixir.` 前缀的 atom。

02

模块调用

`Foo.bar()`、`:lists.reverse/1` 与 `foo:bar()` 最终都指向“模块 atom + 函数 + 元数”。

03

协议边界

跨模块、跨语言传递的数据形状与错误返回。稳定协议比选择哪种表面语法更重要。

双语代码桥

先对齐协议,再看标点

数据协议完全一致:输入两个 atom,输出带标签的 tuple。两边测试甚至可以共享 fixture。

Elixir
defmodule Order do
  @type state :: :new | :paid | :shipped

  @spec transition(state(), atom()) ::
          {:ok, state()} | {:error, :invalid_transition}
  def transition(:new, :pay), do: {:ok, :paid}
  def transition(:paid, :ship), do: {:ok, :shipped}
  def transition(_, _), do: {:error, :invalid_transition}
end
Erlang
-module(order).
-export([transition/2]).

-type state() :: new | paid | shipped.
-spec transition(state(), atom()) ->
  {ok, state()} | {error, invalid_transition}.

transition(new, pay) -> {ok, paid};
transition(paid, ship) -> {ok, shipped};
transition(_, _) -> {error, invalid_transition}.
LAB
可运行实验

证明 term 能穿过语言边界

约 15–25 分钟

从 Elixir 调 Erlang 模块,再从 Erlang 调 Elixir 模块。比较返回值的 inspect 输出。

  1. 01

    在 Mix 项目的 `src/` 放入 `order.erl` 并编译

  2. 02

    在 IEx 调用 `:order.transition(:new, :pay)`

  3. 03

    在 Erlang 代码调用 `'Elixir.Order':transition(new, pay)`

在终端 / shell 中运行
iex -S mix
预期观察
  • 两边都得到 `{ok, paid}` 对应的同一个 tuple term
  • Elixir 模块可通过其底层 atom 从 Erlang 访问
故意弄坏

让一边返回字符串 `"paid"`,另一边仍匹配 atom `paid`。观察接口在语法相似时仍会因 term 不同而失败。

这个实验能证明

普通 BEAM term 可在两种语言模块之间直接传递。

这个实验不能证明

term 可传递不等于所有异常、struct、record 或字符串约定都能无摩擦互用。

快速自测

Elixir 的 `Foo` 模块在 Erlang 中通常如何引用?

本章挑战

订单状态机双实现

扩展取消、退款与重复事件,分别写 Elixir/Erlang 纯函数实现,并用同一张状态转换表验证。

提示 1轻推一下

先写状态 × 事件表,再写代码。

提示 2缩小问题

对重复事件决定幂等还是错误,并写进协议。

提示 3接近实现

不要用进程隐藏不清楚的状态转换。

提示 4用验收标准反推

从下面每一条验收标准倒推一个最小测试。若某条无法写成测试,先把表述改成可观察结果。

完成标准
  • 两版实现返回相同 term 形状
  • 非法转换有明确错误标签
  • spec 与测试覆盖所有状态边
带走这三句话

复习卡

  1. 1先固定 term 协议,再选择语言表达。
  2. 2Elixir 模块名和 alias 最终仍落到 module atom。
  3. 3真正危险的边界常在 string/charlist、struct/record 与异常约定。
继续核对

本章一手资料

Erlang interoperabilityTypespecs