2014-05-13 12 views
7

W statycznie napisanych językach z rodzajami, jak C#, mogę określić w metodzie podpisu, że każdy z kluczy mapy jest atomem, a każda wartość jest listą {string, int} krotka. Jak zdefiniować specyfikację typu dla argumentów funkcji takich jak w Elixir?eliksir: definiowanie specyfikacji typów dla map/hashdicts

PS: jeśli czytasz to i masz ocenę> 1500, możesz utworzyć tag specyfikacji.

+0

nie jestem zaznajomiony z eliksiru, ale twierdzi, że jest "językiem dynamicznym", co zwykle oznacza, że ​​nie ma formalnego systemu typów. Więc ... użyj komentarza? – luqui

+4

ma specyfikacje typów, które mogą być używane przez narzędzie do analizy statycznej Dialyzer - http://elixir-lang.org/docs/stable/Kernel.Typespec.html – tldr

Odpowiedz

12

Można by określić ją tak:

@type bar :: %{atom => [{binary, integer}]} 

@spec foo(bar) :: bar 
def foo(bar), do: bar 

Powyższe definiuje nowy typ, który ma swoją mapę klawiszy atomem do wykazów binarnych krotki/całkowitych, a następnie używa tego typu w specyfikacji typu dla foo.

+0

dla pewności, muszę określić go jako typ wcześniej, nie mogę tego po prostu wstawić? Jeśli tak, czy powinienem zachować wszystkie typy niestandardowe w osobnym module i po prostu je zaimportować, aby uniknąć wklejania definicji typu w wielu modułach? – tldr

+2

Możesz definitywnie ją wstawić, ale trudno mi ją odczytać, jeśli masz wiele wbudowanych typów złożonych. Jest też trochę bardziej jednoznacznie o * czym * jest typ, a nie tylko jego strukturze. Możesz definiować typy w innych modułach i używać ich za pomocą 'Nazwa_typu_typu'. – bitwalker

+0

świetnie, dzięki! W tym sensie analiza statyczna Elixir jest bardziej ziarnista niż Go, ponieważ Go nie pozwala zdefiniować funkcji, które przyjmują twoje niestandardowe typy jako argumenty. (Ignoruj ​​jeśli nie używałeś Go) – tldr

1

inline ciemno to idzie tak:

defmodule LousyCalculator do 
    @spec add(number, number) :: {number, String.t} 
    def add(x, y), do: {x + y, "You need a calculator to do that?!"} 

    @spec multiply(number, number) :: {number, String.t} 
    def multiply(x, y), do: {x * y, "Jeez, come on!"} 
end 

Jeśli oczekujesz struktura to typ to:

@spec struct_returner_and_getter(%Struct_name1{}) :: %Struct_name2{} 

Źródło: http://elixir-lang.org/getting-started/typespecs-and-behaviours.html

Powiązane problemy