Als ich anfing, den Hinweis " Typen, bei denen sie nicht erwartet wurden " zu schreiben , schien es mir, als hÀtte ich es geschafft, Erlang-Typen zur Laufzeit zu bringen, und jetzt kann ich sie im Client-Code auf dem Elixier verwenden. Haha, wie naiv ich war.
Alles, was durch den Link vorgeschlagen wird, funktioniert fĂŒr explizite Typdefinitionen von Verwendungsorten wie use Foo, var: type(). Leider ist dieser Ansatz zum Scheitern verurteilt, wenn wir Typen woanders definieren wollen: daneben im Code mit Modulattributen oder dort in der Konfiguration. Um beispielsweise eine Struktur zu definieren, möchten wir möglicherweise Folgendes schreiben:
# @fields [foo: 42]
# defstruct @fields
@definition var: atom()
use Foo, @definition

Der obige Code ist nicht so, dass er den Typ nicht so behandelt, wie wir es wollen - er wird ĂŒberhaupt nicht erfasst, weil er @definition var: atom()eine Ausnahme auslöst ** (CompileError) undefined function atom/0.
Naiver Ansatz
â « » ( @tsilb, , .) , , , , â .
, , __using__/1: , ( field â type()), â , , , {Module, :type, [params]}. ~q||, , , , AST. quote/1 : foo: ~q|atom()|. , , . . , - , , , , . , , - - - , .
. , erlang â , , . â , , ( ).
Tyyppi
, â , XY . , , â â . Tyyppi.
Code.Typespec, . : . , , , . , , . â Tyyppi.of?/2, , â «»/«» , .
iex|tyyppi|1 Tyyppi.of? GenServer.on_start(), {:ok, self()}
#â true
iex|tyyppi|2 Tyyppi.of? GenServer.on_start(), :ok
#â false
- , Tyyppi.T. Tyyppi.of?/2 - â Tyyppi.of_type?/2.
iex|tyyppi|3 type = Tyyppi.parse(GenServer.on_start)
iex|tyyppi|4 Tyyppi.of_type? type, {:ok, self()}
#â true
, , , , , . :erlang.term_to_binary/1, Config.Provider.
, : . , . , key: type(). Access, upserts. , Ecto.Changeset cast_field/1 validate/1.
, , , , ( , ).
defmodule MyStruct do
import Kernel, except: [defstruct: 1]
import Tyyppi.Struct, only: [defstruct: 1]
@typedoc "The user type defined before `defstruct/1` declaration"
@type my_type :: :ok | {:error, term()}
@defaults foo: :default,
bar: :erlang.list_to_pid('<0.0.0>'),
baz: {:error, :reason}
defstruct foo: atom(), bar: GenServer.on_start(), baz: my_type()
def cast_foo(atom) when is_atom(atom), do: atom
def cast_foo(binary) when is_binary(binary),
do: String.to_atom(binary)
def validate(%{foo: :default} = my_struct), do: {:ok, my_struct}
def validate(%{foo: foo} = my_struct), do: {:error, {:foo, foo}
end
Ich habe keine Ahnung, welchen praktischen Wert diese Bibliothek in der Produktion hat (LĂŒge, ich weiĂ: keine), aber sie kann sicherlich ein groĂer Helfer wĂ€hrend der Entwicklung sein, der es Ihnen ermöglicht, Ihre Suche einzugrenzen und seltsame Fehler zu isolieren, die mit der Dynamik von Typen in Elixir verbunden sind vor allem im Umgang mit externen Quellen.
Der gesamte Bibliothekscode ist wie immer auf dem Github verfĂŒgbar .
Viel SpaĂ beim Tippen zur Laufzeit!