[elixir元编程]改进case语句

本文介绍如何在Elixir中创建新的语法mcase,模仿Kotlin的when语句,允许多个匹配条件共享相同的处理结果。通过宏定义实现了这一功能,并通过测试验证了其正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

elixir的case语句类似于C语言的switch语句, 如下:

case value do
1 -> :one
2 -> :two
end

但是C语言的case语句可以多个case共享一个处理结果:

switch(value){
case 1:
case 2:
return 0;
}

value是1和2都共享了一个处理结果, 这无法在elixir的case语句中做到, 但是

可以在elixir中做到!

参考kotlin的when语句:

when(value){
1,  2 -> "number"
}

和上面的case语句很像啊, 那是不是可以造一个这样的语法呢?

我们进iex看看(第一条是正常的case语句写法, 第二条是我们想要实现的case语句写法)


太好了, 这是个合法的form

一般我们想在elixir中实现一种语法之前, 先使用quote语句来看看这个语法是否合法

如果合法就会返回解析后的ast了

仔细观察上图的结果, 很容易就看出这2条语句变成了什么样的ast

我们只需要写个macro, 将第二个ast转换为第一个ast就行了

为了不和原有的case冲突, 把这个新语法命名为mcase

defmodule Util
  defmacro mcase(value, do: clasuses) do
    clasuses =
      clasuses
      |> Enum.flat_map(fn {:->, line, [match, select]} ->
        match |> Enum.map(&{:->, line, [[&1], select]})
      end)

    quote do
      case unquote(value), do: unquote(clasuses)
    end
  end
end

再写个简单的测试代码

defmodule UtilTest
use ExUnit.Case
import Util
  test "mcase" do
    a =
      mcase 1 do
        1, 2 -> :ok
        3 -> :error
      end

    assert a == :ok

end

运行测试, 通过

这样我们就简单的实现了一个新语法!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值