首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >长生不老宏,引用位字符串模式匹配类型

长生不老宏,引用位字符串模式匹配类型
EN

Stack Overflow用户
提问于 2017-12-13 02:30:34
回答 1查看 184关注 0票数 1

我正在进行一个项目,在这个项目中,我可能会编写大量的表单代码:

代码语言:javascript
复制
defmodule Kind
  defstruct [name1, name2, name3]
  @type t :: %Kind{name1: integer(), name2: integer(), name3: binary()}
  def unpack(input) do
    with <<name1::integer-8>> <- Enum.take(input, 1),
      <<name2::integer-little-32>> <- Enum.take(input, 4),
      <<name3::binary-10>> <- Enum.take(input, 10),
    do: %Kind{name1: name1, name2: name2, name3: name3>>
  end
end

(对于任意一组输入名称和类型,input是一个二进制流,每次生成一个字节)

能够在宏中处理这个问题是非常有用的,这样我就可以简单地编写(例如) use Unpack quote([{name1, integer-8}, {name2, integer-little-32}, {name3, binary-10}]),并为固定大小的任意命名字段自动生成所需的struct、ty清晰度和unpacking函数。甚至可以扩展它,在元组中添加第三个字段来传递一个函数来处理不同大小的类型。不幸的是,当我尝试做一个更简单的版本时(只使用一个大小的字段,并且只匹配1):

代码语言:javascript
复制
defmodule Unpack do
  defmacro testmacro({name, kind}) do
    quote do
      <<unquote(name)::unqote(kind)>> = 1
    end
  end
end

系统告诉我,quote/1的参数无效。我认为这是因为在位字符串模式匹配中使用的“类型”是一种特殊的形式,与一般的位字符串文本一样,而这些特定项在其他任何地方都不使用。

那我怎么才能绕开呢?我有十几种打包的结构,每一种都有五到二十个不同的字段。如果我不这么做,我可能会求助于Vim宏,至少拯救我的手.但是,这并不能真正帮助维护大量非常重复的代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-15 11:09:39

两件事:您在unquote中有一个错误,并且RHS必须是一个二进制文件,这样模式才能匹配。通过这些更改,您的代码适用于我:

代码语言:javascript
复制
defmodule Unpack do
  defmacro unpack({name, kind}) do
    quote do
      <<unquote(name)::unquote(kind)>> = "a"
    end
  end
end

defmodule Main do
  import Unpack

  def main do
    unpack({foo, integer-8})
    IO.inspect foo
  end
end

Main.main

输出:

代码语言:javascript
复制
97
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47784615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档