ich an einem Projekt arbeite, in der ich bin wahrscheinlich eine Menge Code der Form zu schreiben:Elixir Makros unter Angabe von Bitstring patternmatch Typen
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
(für beliebige Sätze von Eingangsnamen und -typen, input
Da es sich um einen binären Datenstrom handelt, der ein Byte nach dem anderen erzeugt)
Es wäre sehr nützlich, dies in einem Makro zu handhaben, so dass ich einfach schreiben könnte (zum Beispiel) use Unpack quote([{name1, integer-8}, {name2, integer-little-32}, {name3, binary-10}])
und automatisch die notwendige struct, typedef erzeugt. und Entpackfunktion für beliebige benannte Felder fester Größe. Könnte es sogar erweitern, fügen Sie ein drittes Feld in den Tupeln hinzu, um eine Funktion zu übergeben, um unterschiedlich große Typen zu behandeln. Leider, wenn ich versuche, eine einfachere Version von, das zu tun (nur eine Größe Feld nehmen, und nur 1 bis es passend):
defmodule Unpack do
defmacro testmacro({name, kind}) do
quote do
<<unquote(name)::unqote(kind)>> = 1
end
end
end
Das System sagt mir es ungültige Argumente für quote/1
bekommt ist. Ich nehme an, das liegt daran, dass die „Typen“ verwendet in Bitstring Pattern-Matching eine spezielle Form sind, wie sie von Bitstring Literale im Allgemeinen, und diese bestimmten Gegenstände sind nicht anderswo verwendet. So
, wie komme ich um das? Ich habe mehr als ein Dutzend Arten von gepackten Strukturen zum Auspacken mit jeweils fünf bis zwanzig verschiedenen Feldern. Wenn ich das nicht tun werde ich wahrscheinlich zu Vim-Makros greifen zumindest meine Hände zu retten ... aber das wird mit mit großen Mengen an äußerst repetitiven Code nicht wirklich helfen zu halten.
Können Sie den vollständigen Code schreiben, die diesen Fehler gibt? Der zweite Snippet funktioniert für mich, wenn ich den Tippfehler (unqote) behebe und eine Binärdatei auf dem RHS benutze (das Muster kann nicht mit einer Ganzzahl verglichen werden). – Dogbert
... Nein, wurde dieser Code direkt aus der IEX-Sitzung Getestet habe ich es in. Offensichtlich ich einen Tippfehler verpasst copypasted. Nun, das ist ziemlich peinlich. Löschen. –
@Dogbert Es kommt mir vor, dass, selbst wenn das Problem klein war, Sie es immer noch beantwortet haben. Gehen Sie weiter, fügen Sie es als Antwort ein und ich werde zustimmen. –