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

Erlang ↔ Elixir 互操作

共享 VM 很容易;设计清楚边界,仍然需要刻意。

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

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

同一 VM 内互调几乎没有仪式感,这很强大,也容易让边界失控。最常见的坑不是函数找不到,而是字符串表示、record 形状、struct 假设和不同异常约定。

学完你能做到

可验证的学习目标

  • 能双向调用模块并处理 module atom
  • 能显式转换 binary、String 与 charlist
  • 能为跨语言异常和返回值建立稳定协议
前置知识
  • 完成共享语义
  • 会用 Mix 与 Rebar3
最小心智模型

先抓住三个词

01

charlist

整数 code point 的 list,Erlang 旧 API 中常见;Elixir 中用 `~c"text"` 表示。

02

record

Erlang 编译期 tuple 语法糖。跨语言直接依赖 tuple 位置很脆弱,优先使用公开访问函数或 map 协议。

03

exception boundary

一边抛出 exception/exit/throw 时,另一边如何捕获并转为稳定错误 tuple 的约定。

双语代码桥

先对齐协议,再看标点

转换发生在边界,核心协议使用带标签 tuple。不要让 charlist 假设渗透整个 Elixir 代码库。

Elixir
defmodule Scheduler do
  @spec submit(binary(), map()) ::
          {:ok, reference()} | {:error, atom()}
  def submit(queue, payload) when is_binary(queue) do
    :job_worker.submit(
      String.to_charlist(queue),
      Map.to_list(payload)
    )
  catch
    :exit, reason -> {:error, normalize_exit(reason)}
  end
end
Erlang
-module(job_worker).
-export([submit/2, call_elixir/1]).

submit(Queue, Payload)
    when is_list(Queue), is_list(Payload) ->
  {ok, make_ref()}.

call_elixir(Value) ->
  'Elixir.Scheduler':normalize(Value).
LAB
可运行实验

把字符串陷阱变成测试

约 15–25 分钟

让 Erlang worker 只接受 charlist;先直接传 Elixir String 触发错误,再在边界转换并固定测试。

  1. 01

    从 Elixir 传入 `"jobs"`,记录 guard 或 function clause 错误

  2. 02

    改用 `String.to_charlist/1`

  3. 03

    为中文队列名加入 round-trip 测试

在终端 / shell 中运行
mix test test/interoperability_test.exs
预期观察
  • binary 与 charlist 匹配不同 guard
  • 显式转换后协议通过
  • Unicode 测试防止按字节错误处理
故意弄坏

从 Erlang 返回一个内部 record tuple,让 Elixir 按位置取值;随后给 record 增加字段,观察脆弱耦合。

这个实验能证明

显式边界转换可让两边对字符串 term 达成一致。

这个实验不能证明

一个成功转换不证明第三方库所有返回路径都遵守同一字符串约定。

快速自测

跨语言调用中,最稳妥的长期返回协议通常是什么?

本章挑战

混合语言 worker

Elixir 提供公共 API 与验证,Erlang gen_server 承担队列状态;两边各自写测试,并互相穿过边界。

提示 1轻推一下

先写 term 协议文档。

提示 2缩小问题

所有转换集中在 adapter 模块。

提示 3接近实现

让 ExUnit 覆盖 Erlang worker,EUnit 覆盖 Elixir normalize 函数。

提示 4用验收标准反推

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

完成标准
  • 两种语言都承担真实职责
  • binary/charlist 和异常转换集中在边界
  • 双向测试能发现协议漂移
带走这三句话

复习卡

  1. 1共享 VM 让调用简单,稳定协议让维护简单。
  2. 2字符串、record 与异常是最常见摩擦面。
  3. 3adapter 应该薄、集中、双向可测试。
继续核对

本章一手资料

Erlang libraries from ElixirString and binaries